Visual Studio 2015 的 UTF-16 编码字符串的内存布局是什么?

What's the memory layout of UTF-16 encoded strings with Visual Studio 2015?

WinAPI 使用 wchar_t 缓冲区。据我了解,我们需要使用 UTF-16 将所有参数编码为 WinAPI。

我们有两个版本的 UTF-16:UTF-16beUTF-16le。让我们编码一个字符串 "Example" 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);
}

Little endian或big endian描述了8位以上的变量在内存中的存储方式。您设计的测试不测试内存布局,它直接使用 wchar_t 类型;整数类型的高位总是高位,无论 CPU 是大端还是小端!

对您的代码的这种修改将显示它的实际工作原理。

std::string charToHex(wchar_t * pch)
{
    const char alphabet[] = "0123456789ABCDEF";

    std::string result;

    unsigned char * pbytes = static_cast<unsigned char *>(pch);

    for (int i = 0; i < sizeof(wchar_t); ++i)
    {
        result.push_back(alphabet[(pbytes[i] & 0xf0) >> 4];
        result.push_back(alphabet[pbytes[i] & 0x0f];
    }

    return std::move(result);
}