【问题标题】:Conversion from std::wstring to LPBYTE从 std::wstring 转换为 LPBYTE
【发布时间】:2014-01-13 08:54:33
【问题描述】:

我有一个没有 MFC 支持的 MS VC++ 程序。 (这就是使用 std::wstring 而不是 CString 的原因。)
我正在使用这种方法将数据流式传输到 Richedit:

DWORD __stdcall MEditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    std::wstring *wsBuffer = (std::wstring *)dwCookie;
    cb = wsBuffer->length();

    for (int i = 0; i < cb; i++)
        *(pbBuff+i) = wsBuffer->c_str()[i];

    *pcb = cb;
    return 0;
}

它以某种方式工作,但我不喜欢使用 for 循环手动转换字符的方式。
有什么函数可以更有效地执行这种转换吗?

【问题讨论】:

  • 你的循环看起来不错。请务必了解您没有更改编码 - 您只需将字符串复制为字节数组。你也可以写(LPBYTE pbBuff = (LPBYTE)&amp;wsBuffer[0];
  • 我正在将宽字符字符串复制到字节数组中。所以上面的类型转换不起作用。 )-:
  • 您可以使用WideCharToMultiByte 并将宽字符串正确转换为适当的编码。
  • 几乎没有任何只支持多字节的 API。在过去 20 年左右的时间里,UTF-16 一直是 Microsoft Windows 的标准。我强烈怀疑你可以只使用 Unicode 版本而忽略所有这些字符转换废话。
  • @NotAnAdmin 你是对的 ;-) 然而在类型转换之后,你得到了一个指向你的 wsBuffer 的指针,就像 LPBYTE 一样。您可以使用任何您喜欢的方式复制它。 wsBuffer.size() 以 2 字节为单位提供长度。

标签: c++


【解决方案1】:

你可以使用WideCharToMultiByte之类的东西。

DWORD __stdcall MEditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
    std::wstring *wsBuffer = (std::wstring *) dwCookie;    
    *pcb = WideCharToMultiByte(CP_ACP, 0, wsBuffer->c_str(), wsBuffer->length(), pbBuff, cb, "?", NULL);
    return 0;
}

您可以随意微调转换参数。

【讨论】:

  • 是的,这就是我要找的。有用。只是 pbBuff 必须像 (LPSTR)pbBuff 一样进行类型转换,并且您有一个错字“1c_str() - 如果您想更正它。谢谢。
【解决方案2】:

看来你必须填充缓冲区 pbBuff 并且除了复制字符串之外别无选择,所以:

for (int i = 0; i < cb; i++)
    *(pbBuff+i) = wsBuffer->c_str()[i];

*pcb = cb;

等价于

cb = min(cb, wsBuffer->length());
CopyMemory(pbBuff, &wsBuffer[0], cb * sizeof(wchar_t));
*pcb = cb;

顺便说一句,使用DWORD 存储指针仅适用于 32 位 Windows,请记住这一点。

【讨论】:

  • 谢谢,但没有。首先,对您的解决方案进行小修复:min(cb, wsBuffer->length());。其次,它不进行转换——在它之后的 pbBuff 中有一个垃圾。最后,我使用的是 64 位 Windows。你的意思是它只适用于程序的 32 位编译。
  • 感谢您的更正,我编辑了我的答案。你能解释一下为什么它不起作用吗?
  • 它只是复制内存。它不执行从两字节字符到单字节字符的转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多