Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

FormatMessage returns a char* containing nulls between each character…why?

When translating error messages I get back a pointer to a string (pMsgBuf) that looks like this

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

The message is there but separated by nulls. Its got to be a parameter that I am passing to Format Message, but have no idea how to fix it.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
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

Should have gotten back my string pointer back with trailing not each character with a null.

Created a test block to confirm that was what I was getting back from format message.

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

     }    

sure enough Joe the string comes out correctly.

>Solution :

You are using the unicode variant which requires a wchar_t* buffer.

Most functions have a "W" and an "A" variant and the plain name #defines to one of them, depending on the compiler option, so FormatMessage resolves to FormatMessageW.

Generally, in Windows, do use unicode and all strings should be std::wstring and wchar_t. Use char/std::string with WideCharToMultiByte with CP_UTF8 for conversions suitable for UTF-8 transmission, say, web post data.

If you use the A version, Windows internally converts everything to UTF-16 according to the system setting’s local page for non-unicode apps. This in recent windows may be UTF-8 but don’t rely on it, it’s a global administrator setting.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading