【发布时间】:2016-06-06 16:33:24
【问题描述】:
WinAPI 使用wchar_t 缓冲区。据我了解,我们需要使用 UTF-16 将所有参数编码到 WinAPI。
我们有两个版本的 UTF-16:UTF-16be 和 UTF-16le。让我们编码一个字符串“示例”0x45 0x78 0x61 0x6d 0x70 0x6c 0x65。使用 UTF-16be 的字节应该这样放置:00 45 00 78 00 61 00 6d 00 70 00 6c 00 65。对于 UTF-16le,它应该是 45 00 78 00 61 00 6d 00 70 00 6c 00 65 00。 (我们省略了 BOM)。同一个字符串的字节表示不同。
根据文档,Windows 使用 UTF-16le。这意味着我们应该使用 UTF-16le 对所有字符串进行编码,否则它将不起作用。
同时,我的编译器 (VS2015) 使用UTF-16be 来处理我硬编码到我的代码中的字符串(比如L"my test string")。但是 WinAPI 可以很好地处理这些字符串。为什么它有效?我错过了什么?
更新 1:
为了测试硬编码字符串的字节表示,我使用了以下代码:
std::string charToHex(wchar_t ch)
{
const char alphabet[] = "0123456789ABCDEF";
std::string result(4, ' ');
result[0] = alphabet[static_cast<unsigned int>((ch & 0xf000) >> 12)];
result[1] = alphabet[static_cast<unsigned int>((ch & 0xf00) >> 8)];
result[2] = alphabet[static_cast<unsigned int>((ch & 0xf0) >> 4)];
result[3] = alphabet[static_cast<unsigned int>(ch & 0xf)];
return std::move(result);
}
【问题讨论】:
-
为什么你认为VS2015正在创建
UTF-16be字符串?我很确定不是。 -
@MarkRansom 我更新了问题。我用上面的代码测试了硬编码的字符串。
-
那么你的示例代码生成了什么?
0045和0078或4500和7800之类的字符串。它应该像前者一样生成字符串。但是,这并没有显示正在使用什么字节顺序,因为您没有访问字符串字节序列,而是将其作为wchar_t值的序列访问。它不显示wchar_t值的字节顺序。 -
sn-p 意义不大,std::string 无法存储 utf-16 编码的字符串。现在你只是看到 0x00 没有在屏幕上显示任何东西。你必须使用 std::wstring() 来获取中文。
-
我投票决定将此问题作为离题结束,因为它遵循以下模式:"
- 为什么会出现这种情况,以及如何解决?"我>。这没用。