You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MessageBox描述仅显示单个字符,FormatMessage类型转换问题求助

问题解答:FormatMessage返回错误字符串仅显示单个字符

问题代码

std::string Window::Exception::TranslateErrorCode(HRESULT hr) noexcept
{
    char* pMsgBuf = nullptr;
    DWORD nMsgLen = FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        nullptr,
        hr,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        reinterpret_cast<LPWSTR>(&pMsgBuf),
        0,
        nullptr
    );
    if (nMsgLen == 0)
    {
        return "Unidentified error code";
    }
    std::string errorString = pMsgBuf;
    LocalFree(pMsgBuf);
    return errorString;
}

问题原因

你的项目启用了Unicode字符集,此时FormatMessage会被预处理器自动替换为宽字符版本FormatMessageW。但你用char*类型的pMsgBuf,通过reinterpret_cast强制转为LPWSTR后,FormatMessageW会把宽字符数据写入char*指向的内存。宽字符(wchar_t)占2字节,比如第一个宽字符是L'X',内存中存储为0xXX 0x00,std::string会把0x00当作字符串结束符,因此只显示第一个字符。

另外直接传LPSTR报错,是因为FormatMessageW要求第五个参数是LPWSTR*类型,和LPSTR*类型不兼容导致的。

解决方案

方案一:使用ANSI版本FormatMessageA

直接调用ANSI版本的FormatMessageA,对应使用char*缓冲区,无需强制类型转换:

std::string Window::Exception::TranslateErrorCode(HRESULT hr) noexcept
{
    char* pMsgBuf = nullptr;
    DWORD nMsgLen = FormatMessageA(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        nullptr,
        hr,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        reinterpret_cast<LPSTR>(&pMsgBuf),
        0,
        nullptr
    );
    if (nMsgLen == 0)
    {
        return "Unidentified error code";
    }
    std::string errorString = pMsgBuf;
    LocalFree(pMsgBuf);
    return errorString;
}

方案二:宽字符处理后转std::string(推荐)

在Unicode环境下,优先使用宽字符版本获取完整错误信息,再转换为std::string:

#include <locale>
#include <codecvt>

std::string Window::Exception::TranslateErrorCode(HRESULT hr) noexcept
{
    wchar_t* pMsgBuf = nullptr;
    DWORD nMsgLen = FormatMessageW(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        nullptr,
        hr,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        reinterpret_cast<LPWSTR>(&pMsgBuf),
        0,
        nullptr
    );
    if (nMsgLen == 0)
    {
        return "Unidentified error code";
    }
    // 将宽字符串转换为UTF-8编码的std::string
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    std::string errorString = converter.to_bytes(pMsgBuf);
    LocalFree(pMsgBuf);
    return errorString;
}

内容的提问来源于stack exchange,提问作者descreetOP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:35:05