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

时间:2016-06-06 16:33:24

标签: windows utf-16 wstring

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);
}

1 个答案:

答案 0 :(得分:3)

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);
}