這篇文章主要講解了“C++跨平臺開發(fā)遇到的問題有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++跨平臺開發(fā)遇到的問題有哪些”吧!
創(chuàng)新互聯(lián)建站主要從事網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)岑鞏,十載網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108
在我的開發(fā)環(huán)境,clang 編碼默認(rèn)是 utf8, VS 是 GB2312(代碼頁是 936),它們都兼容 ASCII。
假如代碼文件中只出現(xiàn)英文,兩端都可編譯。假如代碼中出現(xiàn)中文,文件編碼為 utf8, iOS 編譯沒有問題,VS 會出現(xiàn)編譯錯誤 error C2001。假如設(shè)置編碼為 utf16, VS 編譯沒有問題,而 iOS 會出現(xiàn)編譯錯誤 encoding is not supported。因此假如代碼有中文,需要將源文件編碼修改為 Unicode(UTF8 帶簽名)- 代碼頁 65001。
參見 vs編譯 error C2001: 常量中有換行符 中文無法通過編譯
另外假如包含中文字符串,直接讀取使用,程序運行起來很容易出現(xiàn)亂碼。類似這樣的代碼:
const char* str = "你好啊,世界";
想將 str 的文字在不同平臺都顯示正確,是不可控的??缙脚_代碼不應(yīng)該使用中文,絕對不能用中文定義字符串再讀取,更嚴(yán)格的甚至不能用中文寫注釋。假如要顯示中文字符串,應(yīng)該將其從程序中分離出來,寫在一個 utf8 編碼的配置文件中,再動態(tài)讀取。
我們就碰坑了,我們本意是在導(dǎo)出一個 lua Api 的時候,自動生成對應(yīng)的文檔。有類似這樣的代碼:
ADD_METHOD_WITH_DOC(Context,nv12ToRGBPass, "獲取顏色空間 nv12 到 rgb 的著色器程序","3.2","[Program](#program)", "program",0)
后來發(fā)覺在 Windows 上編譯通過,iOS 編譯不過。修改編碼后, iOS 編譯過了,Windows 上又編譯不過。當(dāng)兩端都編譯過了,但又亂碼了。最后只好都寫成英文,自動生成英文文檔。
在 VS 上,int8_t
實際上是 char 的 typedef,也就是說 int8_t
和 char 是同類型的。但是在 iOS 上,int8_t 和 char 是不同類型的。下列代碼
printf("%d\n", (int)std::is_same<int8_t, char>::value);
在 VS 上輸出 1,在 iOS 上輸出 0。這刷新我認(rèn)知,我一直以為 char 和 int8_t 是相同的。因為這區(qū)別,又踩坑了。
為了方便寫 lua 導(dǎo)出,我們用了 LuaCpp 的庫,里面有這代碼
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;
這里定義了一個 Loki 的 typelist, 包含支持自動轉(zhuǎn)換的類型。typelist 參見書籍C++設(shè)計新思維。
LuaCpp 基本都是模板代碼,假如類型 T 屬于 SupportType,就可執(zhí)行自動轉(zhuǎn)換的代碼,不然就需要手寫轉(zhuǎn)換,假如沒有手寫轉(zhuǎn)換,對于此類型 T, 就會直接崩掉。
這里的代碼很老了,一直都運行正常。直到某個接口出現(xiàn)了 int8_t,于是 VS 上運行正常,iOS 上崩潰了。
同理,int8_t, uint8_t, int16_t, uint16_t 也需要注意。
類似的模板代碼,最好還是乖乖地使用標(biāo)準(zhǔn)庫中的 std::is_integral 吧。不要那么聰明自己手寫 typelist 了。
__VA_ARGS__ 可用于不定參數(shù)的宏。但是它的行為在 VS 和 clang 上是有區(qū)別的。如下面代碼
#include <iostream>#define MY_PRINT(format, ...) printf(format, __VA_ARGS__)int main(int argc, const char* argv[]){MY_PRINT("Hello, World");return 0;}
在 VS 上可以編譯通過。但在 clang 上確實編譯失敗,clang 編譯器的 __VA_ARGS__ 不能展開 0 個變長參數(shù)的。寫成
MY_PRINT("Hello, World, %d", 1);
才可以正確展開。為了展開 0 個參數(shù),需要寫成 ##__VA_ARGS__, 定義為
#define MY_PRINT(format, ...) printf(format, ##__VA_ARGS__)
參考 Variadic macros with zero arguments
一個工程經(jīng)常有多個動態(tài)模塊。在 VS 上,動態(tài)模塊為 dll 文件; iOS 上為 framework 或者 dylib。VS 在跨模塊時,默認(rèn)符號是不導(dǎo)出的。clang 默認(rèn)符號都是導(dǎo)出的。
在 VS 上,當(dāng)想在 A 模塊中定義某個類或者某個函數(shù),讓 B 模塊使用,就需要使用 __declspec(dllexport)
、__declspec(dllimport)
標(biāo)明。通常會定義一些宏,比如。
#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);
通常都沒有問題,假如忘記寫導(dǎo)出,就會鏈接錯誤。但一旦涉及到模板和靜態(tài)變量,這種平臺的差別,就會是個坑。
模板代碼通常會直接寫在頭文件中,比如下代碼。
// myheader.htemplate <typename T>class TemplateClass {public:static std::string str;};template <typename T>std::string TemplateClass<T>::str;
在模塊中,包含了頭文件 myheader.h,就可以使用 TemplateClass 了。假如這時模塊 A 使用語句設(shè)置 str 的值
TemplateClass<int>::str = "Hello, World";
之后模塊 B 讀取 str 的值。
std::string str = TemplateClass<int>::str;
在 VS 中,模塊 A 和模塊 B 雖然都使用 TemplateClass<int>,但因為沒有導(dǎo)出,實際是分離的兩個類,他們的靜態(tài)變量并不會共享。于是就是模塊 A 設(shè)置了 TemplateClass<int>::str,模塊 B 讀取的還是默認(rèn)的空值。
而在 clang 編譯器中,默認(rèn)是導(dǎo)出的。于是模塊 A 和模塊 B 看到的是相同的 TemplateClass<int>,靜態(tài)變量是共享的。于是模塊 A 設(shè)置了 TemplateClass<int>::str,模塊 B 讀取的是設(shè)置后的 "Hello, World"
這種 Bug 比較隱蔽,可以正常編譯,也可以運行,但實際結(jié)果就是不對。我們就踩過類似的坑。
前文說過,我們使用了 LuaCpp 這個庫來導(dǎo)出 lua。這個庫是個模板庫,它包含一些靜態(tài)變量,用來實現(xiàn)自動注冊。我們在模塊 A 中注冊了一批 lua 類。之后在模塊 B 中往 lua 虛擬機(jī)壓注冊過的類對象,在 iOS 上運行正常,但在 Windows 上就異常。因為在模塊 B 中看來,LuaCpp 的記錄中,這些類根本就沒有被注冊過。
感謝各位的閱讀,以上就是“C++跨平臺開發(fā)遇到的問題有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對C++跨平臺開發(fā)遇到的問題有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
網(wǎng)頁名稱:C++跨平臺開發(fā)遇到的問題有哪些
文章轉(zhuǎn)載:http://jinyejixie.com/article46/psieeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計、、網(wǎng)站維護(hù)、網(wǎng)站改版、企業(yè)網(wǎng)站制作、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)