GetLastError() - Получение кода последней ошибки Last-Error в Win 32 API


Все примеры приведены для среды разработки Embarcadero RAD Studio 11 (C++ Builder)

Описание функции GetLastError()

Получает код Last-Error - код последней ошибки вызывающего потока. Код последней ошибки сохраняется для каждого потока. Несколько потоков не перезаписывают код последней ошибки друг друга. Однако функции одного потока могут переписать код последней ошибки даже при успешном выполнении. Прототип функции находится в файле errhandlingapi.h.

WINBASEAPI  _Check_return_  _Post_equals_last_error_  DWORD  WINAPI  GetLastError(VOID);

#define  VOID  void       //- winnt.h




Возвращаемое значение

DWORD
Код последней ошибки вызывающего потока. Коды системных ошибок определяются в WinError.h

В документации к каждой функции, которая задает код последней ошибки, описываются условия возникновения ошибки и конкретные коды из обширного перечня системных ошибок. Функции сторонних производителей могут вводить свои коды ошибок.

Функции, задающие код последней ошибки, могут устанавливать его не только при сбое, но и при успешном выполнении (значение 0).

Если функция не задаёт код ошибки, то она и не сбрасывает его.





Примечание

Функции устанавливают значение кода последней ошибки путем вызова функции SetLastError().

WINBASEAPI  VOID  WINAPI  SetLastError(_In_  DWORD  dwErrCode);

#define  VOID  void       //- winnt.h

Функцию GetLastError() следует вызывать немедленно после ошибочного завершения функции, т.к. следующие функции потока, даже при успешном завершении, могут переписать код последней ошибки.

Чтобы получить строку описания ошибки для системных кодов ошибок, необходимо использовать функцию FormatMessage().

Код ошибки - 32-разрядное значение (DWORD). Бит 29 зарезервирован для кодов ошибок, определяемых сторонним приложением: для системных ошибок он всегда сброшен в ноль. Ошибки стороннего приложения должны устанавливать бит 29 в единицу. Это гарантирует, что код ошибки, определённый сторонним приложением, не конфликтует с кодами ошибок, определенными системой.



Пример использования (с сайта Майкрософт)


void ErrorExit() 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    DWORD dw = GetLastError(); 

    if (FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL) == 0) {
            MessageBox(NULL, TEXT("FormatMessage failed"), TEXT("Error"), MB_OK);
            ExitProcess(dw);
    }

    MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);

    LocalFree(lpMsgBuf);
    ExitProcess(dw); 
}

void main()
{
    // Generate an error

    if (!GetProcessId(NULL))
        ErrorExit();
}