Windows NT在整个Windows NT API中使用Unicode(两个字节宽的UTF-16)作为默认编码方法。如果选择使用ASCII或多字节字符集作为默认字符集,则会将ASCII转换为Unicode。并且使用ASCII字符集将比Unicode慢。
这种转变意味着什么?他们只将ASCII API转换为Unicode API或转换所有字符串?
例如:
如果使用const char* text = "Hello, world!"
创建C / C ++文件。当您在Windows NT上编译它时,编译的二进制文件是否存储“Hello,world!”如Unicode(26字节)还是ASCII(13字节)?
答案 0 :(得分:2)
您必须决定使用哪个API版本:ANSI或Unicode。要么显式使用这些函数(比如用于ANSI的CreateFileA,对于Unicode则使用CreateFileW),要么使用不带'A'或'W'的函数名,_UNICODE预处理器变量决定使用哪两个函数。某些函数需要包含字符串的结构。然后这些结构也有两个版本(如OSVERSIONINFOA和OSVERSIONINFOW)。现在没有充分的理由可以使用ANSI。
但这仅适用于参数,而非内容。如果使用指向数据及其大小的指针将字符串写入文件,则不会进行转换。
回答你的问题:由于你明确使用char
,它占用了13个字节。如果您使用wchar
,它将使用26个字节。你可以写const TCHAR* text = _T("Hello world!");
,然后_UNICODE决定。
答案 1 :(得分:1)
编译器不会更改字符串的类型。它会在你声明它们时对它们进行编码。
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
函数。
为了帮助开发人员处理宽字符串,Microsoft提供的标准C库包含一组用于处理宽字符串字符串的函数(等同于strlen()
,strcat()
a.s.o)。他们的名字通常用str
代替wcs
。
程序员决定使用每个函数的哪个版本。大多数情况下,不需要转换编码(只要你坚持上面的一个)。但是,有些子系统没有选项:您必须将字符串转换为Unicode才能使它们正常工作。
您可以详细了解Windows如何处理API中的字符串:https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407%28v=vs.85%29.aspx
要回答您的问题,Windows不会更改您的字符串。它只在内部从ANSI转换为Unicode,将字符串传递给其API函数的A
版本。它还将Unicode转换回ANSI(如果可能),即A
版本的API函数(例如GetWindowTextA()
)返回的字符串。