Windows NT二进制可执行文件内部const字符串编码

时间:2016-02-06 01:05:07

标签: c++ unicode encoding windows-nt

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字节)?

2 个答案:

答案 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"来自"宽字符") 。一组宏定义将没有后缀的名称映射到AW版本。选择由名为_UNICODE的宏的存在驱动。但是,如果情况需要,程序员可以直接调用AW函数。

为了帮助开发人员处理宽字符串,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())返回的字符串。