GetLastError as std::string

Code

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.

Advertisements

2 thoughts on “GetLastError as std::string

    1. 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:

      std::wstring GetLastErrorStdStrW()
      {
        DWORD error = GetLastError();
        if (error)
        {
          LPVOID lpMsgBuf;
          DWORD bufLen = FormatMessageW(
              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)
          {
            LPCWSTR lpMsgStr = (LPCWSTR)lpMsgBuf;
            std::wstring result(lpMsgStr, lpMsgStr+bufLen);
            
            LocalFree(lpMsgBuf);
      
            return result;
          }
        }
        return std::wstring();
      }
      

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s