If you haven’t a function for this already, feel free to re-use this. Putting it here so I don’t have to look around for it next time I need it.
// Needs Windows constant and type definitions #include <windows.h> // Create a string with last error message std::string GetLastErrorStdStr() { DWORD error = GetLastError(); if (error) { LPVOID lpMsgBuf; DWORD bufLen = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); if (bufLen) { LPCSTR lpMsgStr = (LPCSTR)lpMsgBuf; std::string result(lpMsgStr, lpMsgStr+bufLen); LocalFree(lpMsgBuf); return result; } } return std::string(); }
This function retrieves the last error code, if any, and gets the text message associated with it, which is then converted to a standard string and returned. The main benefits of using this function is that it saves you from having to remember the syntax of FormatMessage, and that the memory used is tidied up.
Note that the FORMAT_MESSAGE_FROM_SYSTEM
flag means only system error messages will be given. If you want to include error messages from your own modules, you’ll need to add the FORMAT_MESSAGE_FROM_HMODULE
flag, and provide the handle to the module. See the FormatMessage documentation for details.
You’re just casting a LPTSTR into a LPCSTR. What if you’re in a Unicode environment?
Like many Windows string functions, the FormatMessage is actually a #define alias, for either FormatMessageA (for ANSI chars) or FormatMessageW (for Unicode wide chars). In this version, I assume FormatMessageA is called. I should probably make that explicit.
In a Unicode environmemt, you’ll want to ensure the W version is used, either by calling it explicitly, or by making sure UNICODE is #defined. In the W version, you don’t get a LPCSTR, but a LPWCSTR – a pointer to an array of wchar_t – so the function would return a std::wstring.
There’s a good rundown of the difference here:
http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring
The code would then look like this: