代码之家  ›  专栏  ›  技术社区  ›  Clark Dixon

FormatMessage返回一个字符*,每个字符之间包含null。。。为什么?

  •  1
  • Clark Dixon  · 技术社区  · 2 年前

    当翻译错误消息时,我会返回一个指向字符串(pMsgBuf)的指针,如下所示

    pMsgBuf = "T\0h\0e\0 \0s\t\0r\0a\0...."

    消息在那里,但用null分隔。它一定是我传递给Format Message的一个参数,但不知道如何修复它。

    {
    char* pMsgBuf;
    // windows will allocate memory for err string and make our pointer point to it
    
    const 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
    );
    // 0 string length returned indicates a failure
    if (nMsgLen == 0)
    {
        return "Unidentified error code";
    }
    char joe[100]{};
    for (int i = 0, y = 0; i < nMsgLen *2; i++)
    {
    if (pMsgBuf[i] != '\0')
        joe[y++] = pMsgBuf[i];
        
    }
    // copy error string from windows-allocated buffer to std::string
    std::string errorString = pMsgBuf;
    // free windows buffer
    size_t size = sizeof(pMsgBuf);
    LocalFree(pMsgBuf);
    return errorString;
    

    }

    Test code with watch active

    应该返回字符串指针,并不是每个字符都有null。

    创建了一个测试块来确认这就是我从格式化消息中得到的内容。

     char joe[100]{};
        for (int i = 0, y = 0; i < nMsgLen *2; i++)
        {
    if (pMsgBuf[i] != '\0')
        joe[y++] = pMsgBuf[i];
    
         }    
    

    果不其然,乔把绳子解开了。

    1 回复  |  直到 2 年前
        1
  •  3
  •   Michael Chourdakis    2 年前

    您使用的unicode变体需要wchar_t*缓冲区。

    大多数函数都有一个“W”和一个“a”变体,根据编译器选项的不同,普通名称#定义为其中一个,因此 FormatMessage 解析为 FormatMessageW .

    通常,在Windows中,请使用unicode,并且所有字符串都应该是std::wstring和wchar_t WideCharToMultiByte 具有 CP_UTF8 用于适用于UTF-8传输的转换,例如web post数据。

    如果您使用A版本,Windows会根据非unicode应用程序的系统设置的本地页面,在内部将所有内容转换为UTF-16。在最近的窗口中,这可能是UTF-8,但不要依赖它,它是全局管理员设置。