wxWidgets随笔(6)-utf8中文(2)
當(dāng)使用Microsoft Visual c++時(shí)不能編譯,需要更改為使用mb_str()(這對(duì)于包含Unicode字符的文件名無(wú)效,請(qǐng)考慮使用wxWidgets類(lèi)和函數(shù)來(lái)處理這些文件名,因?yàn)闃?biāo)準(zhǔn)c++庫(kù)不支持它們)。
另一類(lèi)不兼容的更改是由于修改了一些虛方法來(lái)使用wxString參數(shù)而不是const wxChar參數(shù),從而使它們同時(shí)接受窄字符串和寬字符串。這不是一個(gè)問(wèn)題,如果你只是調(diào)用這些函數(shù),但你需要改變簽名的派生類(lèi)版本,如果你覆蓋他們,否則他們不會(huì)被調(diào)用了。再次強(qiáng)調(diào),確保這個(gè)問(wèn)題不出現(xiàn)的最佳方法是使用警告函數(shù)簽名不匹配的編譯器重新構(gòu)建代碼(可以使用-Woverloaded-virtual g++選項(xiàng))。
最后,一些結(jié)構(gòu)字段,如著名的wxCmdLineEntryDesc::shortName、longName和description字段已被更改為const char類(lèi)型,而不是const wxChar*類(lèi)型,因此,如果將wxT()或_T()與它們的初始化器一起使用,則需要?jiǎng)h除它們。
Unicode是什么?
Unicode是一種字符編碼標(biāo)準(zhǔn),它解決了以前標(biāo)準(zhǔn)(如ASCII標(biāo)準(zhǔn))的缺點(diǎn),使用8位、16位或32位對(duì)每個(gè)字符進(jìn)行編碼。這使得有足夠的代碼點(diǎn)(參見(jiàn)下面的定義)一次性編碼所有世界語(yǔ)言。更多關(guān)于Unicode的細(xì)節(jié)可以在http://www.unicode.org/找到。
從實(shí)用的角度來(lái)看,在為國(guó)際用戶(hù)編寫(xiě)應(yīng)用程序時(shí),使用Unicode幾乎是必需的。此外,任何讀取它沒(méi)有生成的文件或從網(wǎng)絡(luò)中從其他服務(wù)接收數(shù)據(jù)的應(yīng)用程序都應(yīng)該準(zhǔn)備好處理Unicode。
Unicode表示和術(shù)語(yǔ)
在使用Unicode時(shí),定義一些術(shù)語(yǔ)的含義非常重要。
字形是表示字符或字符的一部分的特定圖像(通常是字體的一部分)。任何字符可以有一個(gè)或多個(gè)關(guān)聯(lián)的字形;例如,大寫(xiě)字母“A”可能包含的符號(hào)有:
Unicode為幾乎所有現(xiàn)有的字母/腳本中的每個(gè)字符分配一個(gè)數(shù)字,這個(gè)數(shù)字稱(chēng)為代碼點(diǎn);它通常在文檔手冊(cè)和Unicode網(wǎng)站上表示為U+xxxx,其中xxxx是十六進(jìn)制數(shù)。
注意,通常一個(gè)字符只分配一個(gè)代碼點(diǎn),但也有例外;所謂的預(yù)組合字符(參見(jiàn)http://en.wikipedia.org/wiki/Precomposed_character)或連接。在這些情況下,單個(gè)“字符”可能映射到多個(gè)代碼點(diǎn),反之亦然,多個(gè)字符可能映射到單個(gè)代碼點(diǎn)。
Unicode標(biāo)準(zhǔn)將所有可能的代碼點(diǎn)的空間劃分為平面;一個(gè)平面的范圍是65,536(1000016)個(gè)連續(xù)的Unicode編碼點(diǎn)。平面編號(hào)從0到16,其中第一個(gè)平面是BMP,即基本多語(yǔ)言平面。BMP包含所有現(xiàn)代語(yǔ)言的字符和大量特殊字符。其他平面實(shí)際上主要包含歷史腳本、特殊用途字符或未使用的字符。
代碼點(diǎn)在計(jì)算機(jī)內(nèi)存中表示為一個(gè)或多個(gè)代碼單元的序列,其中一個(gè)代碼單元是一個(gè)內(nèi)存單元:8、16或32位。更準(zhǔn)確地說(shuō),代碼單元是表示用于處理或交換的編碼文本單元的最小位組合。
UTF或Unicode轉(zhuǎn)換格式是將Unicode代碼點(diǎn)映射到代碼單元序列的算法。其中最簡(jiǎn)單的是UTF-32,其中每個(gè)代碼單元由32位(4字節(jié))組成,每個(gè)代碼點(diǎn)總是由單個(gè)代碼單元(固定長(zhǎng)度編碼)表示。(注意,即使UTF-32也不是完全無(wú)關(guān)緊要的,因?yàn)樾《撕痛蠖思軜?gòu)的映射是不同的)。UTF-32通常在Unix系統(tǒng)下用于Unicode字符串的內(nèi)部表示。
另一個(gè)非常普遍的標(biāo)準(zhǔn)是UTF-16,它被Microsoft Windows使用:它使用16位編碼單元(2字節(jié))編碼第一個(gè)(大約)64千個(gè)Unicode編碼點(diǎn)(BMP平面),并使用一對(duì)16位編碼單元來(lái)編碼后面的字符。這些對(duì)被稱(chēng)為代理。因此,UTF16使用可變數(shù)量的代碼單元來(lái)編碼每個(gè)代碼點(diǎn)。
最后,用于外部Unicode存儲(chǔ)(例如文件和網(wǎng)絡(luò)協(xié)議)的最廣泛的編碼是UTF-8,它是面向字節(jié)的,因此避免了UTF-16和UTF-32的endianness二義性。UTF-8使用8位(1字節(jié))的代碼單位;在通常的英文字母之外的代碼點(diǎn)使用可變的字節(jié)數(shù)表示,這使得它在內(nèi)部表示方面的效率低于UTF-32。
作為理解到目前為止所描述的各種概念之間的差異的可視化幫助,查看相同代碼點(diǎn)的不同UTF表示:
在這種特殊情況下,UTF8需要比UTF16更多的空間(3字節(jié)而不是2字節(jié))。
請(qǐng)注意,從C/ c++程序員的角度來(lái)看,由于標(biāo)準(zhǔn)類(lèi)型wchar_t(通常用于表示C/ c++中的Unicode(“寬”)字符串)并不是在所有平臺(tái)上都具有相同的大小,所以情況更加復(fù)雜。它在Unix系統(tǒng)下是4字節(jié),與使用UTF-32的傳統(tǒng)相對(duì)應(yīng),但在Windows下只有2字節(jié),這是與使用UTF-16的操作系統(tǒng)兼容所必需的。
通常使用UTF8時(shí),代碼單元被存儲(chǔ)到char類(lèi)型中,因?yàn)閹缀跛邢到y(tǒng)上的char都是8位寬的;使用UTF16時(shí),通常將代碼單元存儲(chǔ)在wchar_t類(lèi)型中,因?yàn)閣char_t在所有系統(tǒng)上至少是16位的。這也是wxString使用的方法。有關(guān)更多信息,請(qǐng)參見(jiàn)wxString概述。
參見(jiàn)http://unicode.org/glossary/獲得上述術(shù)語(yǔ)的官方定義。
wxWidgets中的Unicode支持
默認(rèn)情況下總是使用Unicode
由于wxWidgets 3.0 Unicode支持始終是啟用的,雖然構(gòu)建沒(méi)有它的庫(kù)仍然是可能的,但不建議再使用它,并且在不久的將來(lái)將不再支持它。這意味著只在內(nèi)部使用Unicode字符串,在Microsoft Windows下使用Unicode系統(tǒng)API,這意味著wxWidgets程序需要Microsoft層才能在Windows 95/98/ME上運(yùn)行Unicode。
但是,與以前版本的wxWidgets的Unicode構(gòu)建模式不同,這種支持基本上是透明的:即使也支持寬字符串(即utf16編碼的wchar_t或utf8編碼的char),您仍然可以繼續(xù)使用窄字符串(即當(dāng)前本地語(yǔ)言環(huán)境編碼的char*)。任何wxWidgets函數(shù)都接受這兩種類(lèi)型的參數(shù),因?yàn)檫@兩種類(lèi)型的字符串都被隱式地轉(zhuǎn)換為wxString
總結(jié)
以上是生活随笔為你收集整理的wxWidgets随笔(6)-utf8中文(2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: wxWidgets随笔(5)-utf8中
- 下一篇: spring boot中打包插件spri