基于C的Win32 API具有许多功能的双重版本,以支持unicode(UTF-16)字符串和较旧的8位代码页字符串。 API还定义了泛型函数和类型,以便稍微抽象出来并允许从同一代码库中编译这两个版本。
Microsoft建议始终使用泛型(请参阅Conventions for Function Prototypes),以便您可以编译这两个版本。但我的问题是 - 通过8位字符串API,我们在这里讨论支持哪些版本的Windows?如果它是Windows 95,那么我的优先级就不再高了:)。如果泛型仅用于支持极端遗留情况,那么直接使用UTF-16调用似乎更容易也更清晰。
答案 0 :(得分:8)
维基百科有一篇详细的文章:https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
首先,我将解释Windows支持的三种类型的字符串文本编码:
char
在C中。尽管名称为“ANSI”,但这不是ASCII不一定是任何特定的ANSI编码,也不是ASCII,但无论当前的语言环境/代码页是什么。char
(其中每个字节为char
。支持的代码页列表是有限的,关键是这不包括UTF-8。质量保证:Difference between MBCS and UTF-8 on Windows)。 MBCS在现代Windows中已弃用,不应在新项目中使用。wchar_t
,即16位。
0x0000
- 0xFFFF
表示的字符。超出此范围的字符无法使用。0xFFFF
之后的代码点由2个或更多wchar_t
个值(4个或更多字节)表示,称为代理对,这意味着二进制字符串的长度(以字节为单位)不一定与字符串的元素长度成正比(在size_t
中),也不一定是打印字符的数量。U+0061, U+0928, U+093F, U+4E9C, U+10083
00 61 09 28 09 3F 4E 9C D8 00 DC 83
wchar_t
个元素Windows 3.x实现了严格为8位的16位Windows API。如果不运行en-US版本,它将使用当前的默认语言环境和代码页设置。它不支持宽字符,但可能支持某种MBCS。
Windows 3.x的“Win32子集”(“Win32s”)插件为Windows 3.x添加了一些Win32功能,包括A
和W
功能,但是{{1函数被存根并在调用时返回失败代码 - 与在Windows 95上的“完整”Win32上看到的行为相同。
Win32,在Windows 9x(95,98,Me)上实现,不支持UTF-16,仅支持“ANSI”或“MBCS”字符串。
一个重要的注意事项是,与Win32s一样,"Wide-character" functions do exist on Windows 9x, but they are stubbed out and when called will return failure codes - a handful of Resource, Command-line and MessageBox-related functions除外,它处理UCS-2字符串(例如W
)。
支持非拉丁字符集需要搞乱代码页和神秘的“多字节”编码选项(记住,不支持UTF-8 - 除了MessageBoxExW
和MultiByteToWideChar
- 这可以用于将UTF-8转换为UTF-16以与Win32 API一起使用。)
2001年,微软发布了一个名为Microsoft Layer for Unicode(MSLU)的Windows 9x附加组件,它将WideCharToMultiByte
函数从失败的存根转换为转换代码,后者将字符串转换回8位格式然后调用W
函数,因此显式使用A
函数的程序可以在Windows 9x上运行。
Windows NT,从一开始就使用NT {3.1(没有3.0版本)附带W
函数接受W
类型的参数。字符串用UCS-2(NT3,NT4)或UTF-16(NT5和更高版本)编码。 Microsoft产品和文档通常使用“Unicode”作为UTF-16或UCS-2的简写。 Win32不支持UTF-8(wchar_t
和MultiByteToWideChar
除外),因此模糊性几乎无法通过。
Windows CE 1.0从一开始就支持UTF-16,考虑其支持级别相当于Windows NT系列。我不知道CE或者是否支持UCS-2而不是UTF-16,或者从一开始就支持UTF-16。
简而言之:
WideCharToMultiByte
(a):https://msdn.microsoft.com/en-us/library/cc194796.aspx
(b):https://support.microsoft.com/en-us/kb/210341
(c):https://en.wikipedia.org/wiki/Microsoft_Layer_for_Unicode
(d):https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
(e):http://www.hpcfactor.com/support/windowsce/wce1.asp
结论:只需使用“Unicode”:即使您正在编写面向Windows 9x的软件,也可以使用Unicode图层,但它仍会运行(尽管类似于Unicode文件名和窗口标题可能很糟糕)。您的代码也可以移植到Windows CE(我很惊讶地看到Windows CE从一开始就支持UTF-16。)