91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++跨平臺開發遇到的問題有哪些

發布時間:2021-11-24 10:45:53 來源:億速云 閱讀:187 作者:iii 欄目:大數據

這篇文章主要講解了“C++跨平臺開發遇到的問題有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++跨平臺開發遇到的問題有哪些”吧!

1. 字符編碼

在我的開發環境,clang 編碼默認是 utf8, VS 是 GB2312(代碼頁是 936),它們都兼容 ASCII。

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

參見 vs編譯 error C2001: 常量中有換行符 中文無法通過編譯

另外假如包含中文字符串,直接讀取使用,程序運行起來很容易出現亂碼。類似這樣的代碼:

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

想將 str 的文字在不同平臺都顯示正確,是不可控的。跨平臺代碼不應該使用中文,絕對不能用中文定義字符串再讀取,更嚴格的甚至不能用中文寫注釋。假如要顯示中文字符串,應該將其從程序中分離出來,寫在一個 utf8 編碼的配置文件中,再動態讀取。

我們就碰坑了,我們本意是在導出一個 lua Api 的時候,自動生成對應的文檔。有類似這樣的代碼:

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

后來發覺在 Windows 上編譯通過,iOS 編譯不過。修改編碼后, iOS 編譯過了,Windows 上又編譯不過。當兩端都編譯過了,但又亂碼了。最后只好都寫成英文,自動生成英文文檔。

2. int8_t 和 char

在 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。這刷新我認知,我一直以為 char 和 int8_t 是相同的。因為這區別,又踩坑了。

為了方便寫 lua 導出,我們用了 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, 包含支持自動轉換的類型。typelist 參見書籍C++設計新思維。

LuaCpp 基本都是模板代碼,假如類型 T 屬于 SupportType,就可執行自動轉換的代碼,不然就需要手寫轉換,假如沒有手寫轉換,對于此類型 T, 就會直接崩掉。

這里的代碼很老了,一直都運行正常。直到某個接口出現了 int8_t,于是 VS 上運行正常,iOS 上崩潰了。

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

類似的模板代碼,最好還是乖乖地使用標準庫中的 std::is_integral 吧。不要那么聰明自己手寫 typelist 了。

3. __VA_ARGS__

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

#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 個變長參數的。寫成

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

才可以正確展開。為了展開 0 個參數,需要寫成 ##__VA_ARGS__, 定義為

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

參考 Variadic macros with zero arguments

4. 跨 dll 模塊的靜態變量

一個工程經常有多個動態模塊。在 VS 上,動態模塊為 dll 文件; iOS 上為 framework 或者 dylib。VS 在跨模塊時,默認符號是不導出的。clang 默認符號都是導出的。

在 VS 上,當想在 A 模塊中定義某個類或者某個函數,讓 B 模塊使用,就需要使用 __declspec(dllexport)__declspec(dllimport) 標明。通常會定義一些宏,比如。

#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

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

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

通常都沒有問題,假如忘記寫導出,就會鏈接錯誤。但一旦涉及到模板和靜態變量,這種平臺的差別,就會是個坑。

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

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

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

TemplateClass<int>::str = "Hello, World";

之后模塊 B 讀取 str 的值。

std::string str = TemplateClass<int>::str;

在 VS 中,模塊 A 和模塊 B 雖然都使用 TemplateClass<int>,但因為沒有導出,實際是分離的兩個類,他們的靜態變量并不會共享。于是就是模塊 A 設置了 TemplateClass<int>::str,模塊 B 讀取的還是默認的空值。

而在 clang 編譯器中,默認是導出的。于是模塊 A 和模塊 B 看到的是相同的 TemplateClass<int>,靜態變量是共享的。于是模塊 A 設置了 TemplateClass<int>::str,模塊 B 讀取的是設置后的 "Hello, World"

這種 Bug 比較隱蔽,可以正常編譯,也可以運行,但實際結果就是不對。我們就踩過類似的坑。

前文說過,我們使用了 LuaCpp 這個庫來導出 lua。這個庫是個模板庫,它包含一些靜態變量,用來實現自動注冊。我們在模塊 A 中注冊了一批 lua 類。之后在模塊 B 中往 lua 虛擬機壓注冊過的類對象,在 iOS 上運行正常,但在 Windows 上就異常。因為在模塊 B 中看來,LuaCpp 的記錄中,這些類根本就沒有被注冊過。

感謝各位的閱讀,以上就是“C++跨平臺開發遇到的問題有哪些”的內容了,經過本文的學習后,相信大家對C++跨平臺開發遇到的問題有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

辽中县| 容城县| 独山县| 综艺| 始兴县| 新平| 牡丹江市| 武鸣县| 周口市| 同德县| 翼城县| 武城县| 腾冲县| 南充市| 民丰县| 克拉玛依市| 通辽市| 武强县| 崇明县| 二连浩特市| 县级市| 察哈| 宜昌市| 长沙市| 嫩江县| 包头市| 平远县| 冀州市| 云南省| 洪洞县| 浏阳市| 刚察县| 获嘉县| 静宁县| 灵璧县| 碌曲县| 孝义市| 安达市| 衡阳县| 华容县| 安多县|