哪些版本的Windows不支持unicode API调用?

时间:2016-02-11 01:03:56

标签: c windows unicode

基于C的Win32 API具有许多功能的双重版本,以支持unicode(UTF-16)字符串和较旧的8位代码页字符串。 API还定义了泛型函数和类型,以便稍微抽象出来并允许从同一代码库中编译这两个版本。

Microsoft建议始终使用泛型(请参阅Conventions for Function Prototypes),以便您可以编译这两个版本。但我的问题是 - 通过8位字符串API,我们在这里讨论支持哪些版本的Windows?如果它是Windows 95,那么我的优先级就不再高了:)。如果泛型仅用于支持极端遗留情况,那么直接使用UTF-16调用似乎更容易也更清晰。

1 个答案:

答案 0 :(得分:8)

维基百科有一篇详细的文章:https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows

首先,我将解释Windows支持的三种类型的字符串文本编码:

  1. “ANSI”= 8位编码 - char在C中。尽管名称为“ANSI”,但这不是ASCII不一定是任何特定的ANSI编码,也不是ASCII,但无论当前的语言环境/代码页是什么。
  2. “MBCS”=多字节字符集编码 - C中的char(其中每个字节为char。支持的代​​码页列表是有限的,关键是这不包括UTF-8。质量保证:Difference between MBCS and UTF-8 on Windows)。 MBCS在现代Windows中已弃用,不应在新项目中使用。
  3. “Unicode”= UTF-16(或NT3 / NT4中的UCS-2) - C中的wchar_t,即16位。
    • 在UCS-2下,只能使用由代码点0x0000 - 0xFFFF表示的字符。超出此范围的字符无法使用。
    • 在UTF-16(Windows 2000及更高版本)中,0xFFFF之后的代码点由2个或更多wchar_t个值(4个或更多字节)表示,称为代理对,这意味着二进制字符串的长度(以字节为单位)不一定与字符串的元素长度成正比(在size_t中),也不一定是打印字符的数量。
    • 同时考虑连字和变音符号之类的内容也会破坏编程代码经常出现的byte / element / printed-char计数等价假设。
    • 例如,请考虑此代码点字符串:U+0061, U+0928, U+093F, U+4E9C, U+10083
      • 在UTF-16 Big-Endian字节中,这是00 61 09 28 09 3F 4E 9C D8 00 DC 83
      • 这是12个字节
      • ...这是6 wchar_t个元素
      • ...但代表5个字符
      • ...呈现为4个打印字符(由于第2个和第3个字符之间的连接)。
  4. Windows 3.x

    Windows 3.x实现了严格为8位的16位Windows API。如果不运行en-US版本,它将使用当前的默认语言环境和代码页设置。它不支持宽字符,但可能支持某种MBCS。

    Windows 3.x的“Win32子集”(“Win32s”)插件为Windows 3.x添加了一些Win32功能,包括AW功能,但是{{1函数被存根并在调用时返回失败代码 - 与在Windows 95上的“完整”Win32上看到的行为相同。

    Windows 95,98,Me:

    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 - 除了MessageBoxExWMultiByteToWideChar - 这可以用于将UTF-8转换为UTF-16以与Win32 API一起使用。)

    2001年,微软发布了一个名为Microsoft Layer for Unicode(MSLU)的Windows 9x附加组件,它将WideCharToMultiByte函数从失败的存根转换为转换代码,后者将字符串转换回8位格式然后调用W函数,因此显式使用A函数的程序可以在Windows 9x上运行。

    Windows NT

    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_tMultiByteToWideChar除外),因此模糊性几乎无法通过。

    Windows CE

    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。)