【问题标题】:What's the memory layout of UTF-16 encoded strings with Visual Studio 2015?Visual Studio 2015 的 UTF-16 编码字符串的内存布局是什么?
【发布时间】:2016-06-06 16:33:24
【问题描述】:

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

我们有两个版本的 UTF-16:UTF-16beUTF-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 我更新了问题。我用上面的代码测试了硬编码的字符串。
  • 那么你的示例代码生成了什么? 0045007845007800 之类的字符串。它应该像前者一样生成字符串。但是,这并没有显示正在使用什么字节顺序,因为您没有访问字符串字节序列,而是将其作为wchar_t 值的序列访问。它不显示 wchar_t 值的字节顺序。
  • sn-p 意义不大,std::string 无法存储 utf-16 编码的字符串。现在你只是看到 0x00 没有在屏幕上显示任何东西。你必须使用 std::wstring() 来获取中文。
  • 我投票决定将此问题作为离题结束,因为它遵循以下模式:" - 为什么会出现这种情况,以及如何解决?"我>。这没用。

标签: windows utf-16 wstring


【解决方案1】:

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

【讨论】:

  • 现在我明白我是如何失败的了……非常感谢
猜你喜欢
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 2014-06-21
  • 2015-10-31
  • 2014-05-17
  • 2013-08-17
  • 1970-01-01
  • 2023-04-11
相关资源
最近更新 更多