Windows NT 使用 Unicode(两个字节宽的 UTF-16)作为整个 Windows NT API 的默认编码方法。如果您选择使用 ASCII 或多字节字符集作为默认字符集,它们会将 ASCII 转换为 Unicode。而且使用 ASCII 字符集会比 Unicode 慢。这种转变意味着什么?他们只将 ASCII API 转换为 Unicode API 还是转换所有字符串?例如:如果您使用const char* text = "Hello, world!"
. 在 Windows NT 上编译它时,编译后的二进制文件是否存储“Hello, world!”?作为 Unicode(26 字节)还是 ASCII(13 字节)?
2 回答
您必须决定使用哪个 API 版本:ANSI 或 Unicode。要么显式使用函数(如 ANSI 的 CreateFileA,Unicode 的 CreateFileW),要么使用不带“A”或“W”的函数名称,_UNICODE 预处理器变量决定使用这两个函数中的哪一个。某些函数需要包含字符串的结构。然后还有这些结构的两个版本(如 OSVERSIONINFOA 和 OSVERSIONINFOW)。现在没有充分的理由使用 ANSI。
但这仅适用于arguments,而不适用于 content。如果您使用指向数据及其大小的指针将字符串写入文件,则不会进行任何转换。
回答您的问题:由于您明确使用char
它占用 13 个字节。如果您使用wchar
它,它将使用 26 个字节。你可以写const TCHAR* text = _T("Hello world!");
,然后 _UNICODE 会决定。
编译器不会更改字符串的类型。它会在你声明它们时对它们进行编码。
Windows NT 及其后续版本(2000、XP、2003、Vista、7、8、8.1、10)在内部使用 2 字节字符(称为“宽字符”)。Windows NT 曾经使用这种UCS-2
编码;从 Windows 2000 开始,它切换到UTF-16LE
.
对于大多数处理字符串的 API 函数,它们有 2 个不同的版本;处理 ANSI 字符串A
的名称以 结尾,另一个名称以W
(“宽字符”中的“W”)结尾。一组宏定义将不带后缀的名称映射到版本A
或W
版本。选择是由名为 的宏的存在驱动的_UNICODE
。但是,如果情况需要,程序员可以自由地直接调用A
或W
函数。
为了帮助开发人员处理宽字符串,微软提供的标准 C 库包含一组处理宽字符字符串的函数(相当于strlen()
, strcat()
aso)。他们的名字通常str
被替换为wcs
.
程序员是决定使用每个函数的哪个版本的人。大多数时候不需要转换编码(只要你坚持以上之一)。但是,有些子系统没有选项:您必须将字符串转换为 Unicode 才能使它们工作。
您可以阅读有关 Windows 如何处理 API 中的字符串的更多信息:https ://msdn.microsoft.com/en-us/library/windows/desktop/ff381407%28v=vs.85%29.aspx
为了回答您的问题,Windows 不会更改您的字符串。它仅在内部将字符串从 ANSI 转换为 Unicode,以传递给A
其 API 函数的版本。它还将 Unicode 转换回 ANSI(如果可能),即由A
API 函数版本返回的字符串(GetWindowTextA()
例如 )。