我正在使用旧版应用程序,并且正在尝试找出使用该选项编译的应用程序Multi byte character set
和Not Set
使用该Character Set
选项编译的应用程序之间的区别。
我知道使用Multi byte character set
定义编译_MBCS
允许使用多字节字符集代码页,而使用Not set
不定义编译_MBCS
,在这种情况下只允许使用单字节字符集代码页。
在使用的情况下Not Set
,我假设我们只能使用此页面上的单字节字符集代码页:http: //msdn.microsoft.com/en-gb/goglobal/bb964654.aspx
因此,我认为Not Set
使用的是正确的,应用程序将无法编码和编写或读取远东语言,因为它们是在双字节字符集代码页(当然还有 Unicode)中定义的?
接下来,如果Multi byte character
定义了 set,单字节和多字节字符集代码页都可用,还是只有多字节字符集代码页?我猜它必须同时支持欧洲语言。
谢谢,
安迪
延伸阅读
这些页面上的答案没有回答我的问题,但有助于我的理解: 关于 Visual Studio 2010 中的“字符集”选项
研究
所以,就像工作研究一样......我的语言环境设置为日语
对硬编码字符串的影响
char *foo = "Jap text: テスト";
wchar_t *bar = L"Jap text: テスト";
编译Unicode
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis(代码页 932)
*bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 或 UCS-2
编译Multi byte character set
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis(代码页 932)
*bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 或 UCS-2
编译Not Set
*foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis(代码页 932)
*bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 或 UCS-2
结论: 字符编码对硬编码字符串没有任何影响。尽管如上定义字符似乎使用了 Locale 定义的代码页,而 wchar_t 似乎使用了 UCS-2 或 UTF-16。
在 W/A 版本的 Win32 API 中使用编码字符串
因此,使用以下代码:
char *foo = "C:\\Temp\\テスト\\テa.txt";
wchar_t *bar = L"C:\\Temp\\テスト\\テw.txt";
CreateFileA(bar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CreateFileW(foo, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
编译Unicode
结果:创建了两个文件
编译Multi byte character set
结果:创建了两个文件
编译Not set
结果:创建了两个文件
结论:
无论选择何种字符集,API的A
和版本都期望相同的编码。W
由此,也许我们可以假设所有Character Set
选项都是在 API 版本之间切换。因此,该A
版本始终需要当前代码页编码中的字符串,并且该W
版本始终需要 UTF-16 或 UCS-2。
使用 W 和 A Win32 API 打开文件
所以使用以下代码:
char filea[MAX_PATH] = {0};
OPENFILENAMEA ofna = {0};
ofna.lStructSize = sizeof ( ofna );
ofna.hwndOwner = NULL ;
ofna.lpstrFile = filea ;
ofna.nMaxFile = MAX_PATH;
ofna.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofna.nFilterIndex =1;
ofna.lpstrFileTitle = NULL ;
ofna.nMaxFileTitle = 0 ;
ofna.lpstrInitialDir=NULL ;
ofna.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
wchar_t filew[MAX_PATH] = {0};
OPENFILENAMEW ofnw = {0};
ofnw.lStructSize = sizeof ( ofnw );
ofnw.hwndOwner = NULL ;
ofnw.lpstrFile = filew ;
ofnw.nMaxFile = MAX_PATH;
ofnw.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0";
ofnw.nFilterIndex =1;
ofnw.lpstrFileTitle = NULL;
ofnw.nMaxFileTitle = 0 ;
ofnw.lpstrInitialDir=NULL ;
ofnw.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ;
GetOpenFileNameA(&ofna);
GetOpenFileNameW(&ofnw);
并选择:
- C:\Temp\テスト\テopenw.txt
- C:\Temp\テスト\テopenw.txt
产量:
编译时使用Unicode
*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis(代码页 932)
*filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 或 UCS-2
编译时使用Multi byte character set
*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis(代码页 932)
*filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 或 UCS-2
编译时使用Not Set
*filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis(代码页 932)
*filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 或 UCS-2
结论:
同样,该Character Set
设置与 Win32 API 的行为无关。该A
版本似乎总是返回一个带有活动代码页编码的字符串,并且该版本W
总是返回 UTF-16 或 UCS-2。我实际上可以在这个很好的答案中看到这一点:https ://stackoverflow.com/a/3299860/187100 。
终极结论
W
汉斯似乎是正确的,他说除了将 Win32 API 更改为使用或之外,定义实际上并没有任何魔力A
。Not Set
因此,我真的看不出和之间有什么区别Multi byte character set
。