真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++跨平臺(tái)開(kāi)發(fā)遇到的問(wèn)題有哪些

這篇文章主要講解了“C++跨平臺(tái)開(kāi)發(fā)遇到的問(wèn)題有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“C++跨平臺(tái)開(kāi)發(fā)遇到的問(wèn)題有哪些”吧!

創(chuàng)新互聯(lián)建站主要從事網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)岑鞏,十載網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18982081108

1. 字符編碼

在我的開(kāi)發(fā)環(huán)境,clang 編碼默認(rèn)是 utf8, VS 是 GB2312(代碼頁(yè)是 936),它們都兼容 ASCII。

假如代碼文件中只出現(xiàn)英文,兩端都可編譯。假如代碼中出現(xiàn)中文,文件編碼為 utf8, iOS 編譯沒(méi)有問(wèn)題,VS 會(huì)出現(xiàn)編譯錯(cuò)誤 error C2001。假如設(shè)置編碼為 utf16, VS 編譯沒(méi)有問(wèn)題,而 iOS 會(huì)出現(xiàn)編譯錯(cuò)誤 encoding is not supported。因此假如代碼有中文,需要將源文件編碼修改為 Unicode(UTF8 帶簽名)- 代碼頁(yè) 65001。

參見(jiàn) vs編譯 error C2001: 常量中有換行符 中文無(wú)法通過(guò)編譯

另外假如包含中文字符串,直接讀取使用,程序運(yùn)行起來(lái)很容易出現(xiàn)亂碼。類似這樣的代碼:

const char* str = "你好啊,世界";

想將 str 的文字在不同平臺(tái)都顯示正確,是不可控的。跨平臺(tái)代碼不應(yīng)該使用中文,絕對(duì)不能用中文定義字符串再讀取,更嚴(yán)格的甚至不能用中文寫注釋。假如要顯示中文字符串,應(yīng)該將其從程序中分離出來(lái),寫在一個(gè) utf8 編碼的配置文件中,再動(dòng)態(tài)讀取。

我們就碰坑了,我們本意是在導(dǎo)出一個(gè) lua Api 的時(shí)候,自動(dòng)生成對(duì)應(yīng)的文檔。有類似這樣的代碼:

ADD_METHOD_WITH_DOC(Context,nv12ToRGBPass, "獲取顏色空間 nv12 到 rgb 的著色器程序","3.2","[Program](#program)", "program",0)

后來(lái)發(fā)覺(jué)在 Windows 上編譯通過(guò),iOS 編譯不過(guò)。修改編碼后, iOS 編譯過(guò)了,Windows 上又編譯不過(guò)。當(dāng)兩端都編譯過(guò)了,但又亂碼了。最后只好都寫成英文,自動(dòng)生成英文文檔。

2. int8_t 和 char

在 VS 上,int8_t 實(shí)際上是 char 的 typedef,也就是說(shuō) int8_t 和 char 是同類型的。但是在 iOS 上,int8_t 和 char 是不同類型的。下列代碼

printf("%d\n", (int)std::is_same::value);

在 VS 上輸出 1,在 iOS 上輸出 0。這刷新我認(rèn)知,我一直以為 char 和 int8_t 是相同的。因?yàn)檫@區(qū)別,又踩坑了。

為了方便寫 lua 導(dǎo)出,我們用了 LuaCpp 的庫(kù),里面有這代碼

typedef LOKI_TYPELIST_15(bool, char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, float, double,std::string, luaObject, luatable, int64_t) SupportType;

這里定義了一個(gè) Loki 的 typelist, 包含支持自動(dòng)轉(zhuǎn)換的類型。typelist 參見(jiàn)書籍C++設(shè)計(jì)新思維。

LuaCpp 基本都是模板代碼,假如類型 T 屬于 SupportType,就可執(zhí)行自動(dòng)轉(zhuǎn)換的代碼,不然就需要手寫轉(zhuǎn)換,假如沒(méi)有手寫轉(zhuǎn)換,對(duì)于此類型 T, 就會(huì)直接崩掉。

這里的代碼很老了,一直都運(yùn)行正常。直到某個(gè)接口出現(xiàn)了 int8_t,于是 VS 上運(yùn)行正常,iOS 上崩潰了。

同理,int8_t, uint8_t, int16_t, uint16_t 也需要注意。

類似的模板代碼,最好還是乖乖地使用標(biāo)準(zhǔn)庫(kù)中的 std::is_integral 吧。不要那么聰明自己手寫 typelist 了。

3. __VA_ARGS__

__VA_ARGS__ 可用于不定參數(shù)的宏。但是它的行為在 VS 和 clang 上是有區(qū)別的。如下面代碼

#include #define MY_PRINT(format, ...) printf(format, __VA_ARGS__)int main(int argc, const char* argv[]){MY_PRINT("Hello, World");return 0;}

在 VS 上可以編譯通過(guò)。但在 clang 上確實(shí)編譯失敗,clang 編譯器的 __VA_ARGS__ 不能展開(kāi) 0 個(gè)變長(zhǎng)參數(shù)的。寫成

MY_PRINT("Hello, World, %d", 1);

才可以正確展開(kāi)。為了展開(kāi) 0 個(gè)參數(shù),需要寫成 ##__VA_ARGS__, 定義為

#define MY_PRINT(format, ...) printf(format, ##__VA_ARGS__)

參考 Variadic macros with zero arguments

4. 跨 dll 模塊的靜態(tài)變量

一個(gè)工程經(jīng)常有多個(gè)動(dòng)態(tài)模塊。在 VS 上,動(dòng)態(tài)模塊為 dll 文件; iOS 上為 framework 或者 dylib。VS 在跨模塊時(shí),默認(rèn)符號(hào)是不導(dǎo)出的。clang 默認(rèn)符號(hào)都是導(dǎo)出的。

在 VS 上,當(dāng)想在 A 模塊中定義某個(gè)類或者某個(gè)函數(shù),讓 B 模塊使用,就需要使用 __declspec(dllexport)、__declspec(dllimport) 標(biāo)明。通常會(huì)定義一些宏,比如。

#if defined(OF_WIN32) || defined(_WIN32) || defined(WIN32)#   ifdef MODULE_A_API_LIB#       define MODULE_A_API __declspec(dllexport)#   else#       define MODULE_A_API __declspec(dllimport)#   endif#else#   define MODULE_A_API#endif

之后需要跨模塊使用的函數(shù)或者類寫成

class MODULE_A_API TestClass {};MODULE_A_API void myfunction(int a, int b);

通常都沒(méi)有問(wèn)題,假如忘記寫導(dǎo)出,就會(huì)鏈接錯(cuò)誤。但一旦涉及到模板和靜態(tài)變量,這種平臺(tái)的差別,就會(huì)是個(gè)坑。

模板代碼通常會(huì)直接寫在頭文件中,比如下代碼。

// myheader.htemplate class TemplateClass {public:static std::string str;};template std::string TemplateClass::str;

在模塊中,包含了頭文件 myheader.h,就可以使用 TemplateClass 了。假如這時(shí)模塊 A 使用語(yǔ)句設(shè)置 str 的值

TemplateClass::str = "Hello, World";

之后模塊 B 讀取 str 的值。

std::string str = TemplateClass::str;

在 VS 中,模塊 A 和模塊 B 雖然都使用 TemplateClass,但因?yàn)闆](méi)有導(dǎo)出,實(shí)際是分離的兩個(gè)類,他們的靜態(tài)變量并不會(huì)共享。于是就是模塊 A 設(shè)置了 TemplateClass::str,模塊 B 讀取的還是默認(rèn)的空值。

而在 clang 編譯器中,默認(rèn)是導(dǎo)出的。于是模塊 A 和模塊 B 看到的是相同的 TemplateClass,靜態(tài)變量是共享的。于是模塊 A 設(shè)置了 TemplateClass::str,模塊 B 讀取的是設(shè)置后的 "Hello, World"

這種 Bug 比較隱蔽,可以正常編譯,也可以運(yùn)行,但實(shí)際結(jié)果就是不對(duì)。我們就踩過(guò)類似的坑。

前文說(shuō)過(guò),我們使用了 LuaCpp 這個(gè)庫(kù)來(lái)導(dǎo)出 lua。這個(gè)庫(kù)是個(gè)模板庫(kù),它包含一些靜態(tài)變量,用來(lái)實(shí)現(xiàn)自動(dòng)注冊(cè)。我們?cè)谀K A 中注冊(cè)了一批 lua 類。之后在模塊 B 中往 lua 虛擬機(jī)壓注冊(cè)過(guò)的類對(duì)象,在 iOS 上運(yùn)行正常,但在 Windows 上就異常。因?yàn)樵谀K B 中看來(lái),LuaCpp 的記錄中,這些類根本就沒(méi)有被注冊(cè)過(guò)。

感謝各位的閱讀,以上就是“C++跨平臺(tái)開(kāi)發(fā)遇到的問(wèn)題有哪些”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)C++跨平臺(tái)開(kāi)發(fā)遇到的問(wèn)題有哪些這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!


新聞名稱:C++跨平臺(tái)開(kāi)發(fā)遇到的問(wèn)題有哪些
轉(zhuǎn)載來(lái)于:http://weahome.cn/article/psieeg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部