[WinAPI] Cum utilizam corect GetLastError?

Folosire Windows API in programe C/C++ (forum moderat)

[WinAPI] Cum utilizam corect GetLastError?

Mesajde Ovidiu Cucu » 19 Aug 2011, 12:51

Intrebare
Cum utilizam corect GetLastError pentru a obtine codul de eroare dupa un apel de functie WinAPI?

Raspuns
  • In primul rand, aruncam un ochi in documentatie sa vedem daca functia data seteaza last-error code (valoarea care va fi returnata de GetLastError). Daca da, de obicei exista o referire la GetLastError in sectiunea "Return Values" (exemplu: "To get extended error information, call GetLastError").
  • Vedem ce valoare intoarce functia in caz de eroare. Poate fi zero, un handle NULL sau o alta valoare cum ar fi INVALID_HANDLE_VALUE.
  • In fine, testam in cod valoarea returnata iar in caz de eroare chemam GetLastError.
Exemple
Cod: Selectaţi tot
   BOOL bRet = ::DeleteFile(pszFileName);
   if(! bRet) // DeleteFile function has failed
   {
      DWORD dwError = ::GetLastError();
      // ...
   }
Cod: Selectaţi tot
   HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
   if(NULL == hProcess) // OpenProcess function has failed
   {
      DWORD dwError = ::GetLastError();
      // ...
   }
Cod: Selectaţi tot
   HANDLE hFind = ::FindFirstFile(pszFileName, &findData);
   if(INVALID_HANDLE_VALUE == hFind) // FindFirstFile function has failed
   {
      DWORD dwError = ::GetLastError();
      // ...
   }


Note
  1. Nu toate functiile WinAPI seteaza pe zero last-error code in caz de succes.
    O greseala destul de frecventa pe care o fac programatorii este de a chema GetLastError fara ca mai inainte sa vada daca functia a esuat sau nu. In exemplul urmator, GetLastError intoarce valoarea 8 (ERROR_NOT_ENOUGH_MEMORY) chiar daca functia LoadImage a avut succes.
    Cod: Selectaţi tot
       HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, pszFileName,
          IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);

       DWORD dwError = ::GetLastError();
       // This is wrong! You have to call GetLastError only if hBitmap is NULL.
  2. Unele functii WinAPI (e.g. RegQueryValueEx) intorc direct codul de eroare deci nu mai are sens sa chemam GetLastError.
    In orice caz, trebuie mai intai de vazut in documentate daca o functie data seteaza last-error sau nu.

Vezi si
Avatar utilizator
Ovidiu Cucu
Fondator
Fondator
 
Mesaje: 3776
Membru din: 11 Iul 2007, 16:10
Localitate: Iasi
Judet: Iaşi

Re: [WinAPI] Cum utilizam corect GetLastError?

Mesajde mesajflaviu » 17 Mai 2013, 10:28

Ca o completare, rezultatul ::GetLastError se poate "traduce" in text in modul urmator:
Cod: Selectaţi tot
// MyFile.h

CString GetErrorString(const DWORD dwError);


Cod: Selectaţi tot
// MyFile.cpp

CString GetErrorString(const DWORD dwError)
{
    CString strError;
    LPTSTR lpszBuffer = NULL;
    if(0 == ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, dwError, 0, (LPTSTR)&lpszBuffer, 0, NULL))
    { 
        // FormatMessage failed
        strError.Format(_T("Unknown error: 0x%08X"), dwError);
    }
    else // success
    {     
        strError = lpszBuffer;
        strError.TrimRight(_T("\r\n")); // remove CRLF
        ::LocalFree(lpszBuffer);
    }
    return strError;
}


si un exemplu de folosire:
Cod: Selectaţi tot
   HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, lpszPathName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
   if(NULL == hBitmap)
   {
      CString sMessage;
      const DWORD dwError = ::GetLastError();
      sMessage.Format(_T("Failed to load '%s' file. Reason: %s\n"), lpszPathName, GetErrorString(dwError));
      AfxMessageBox(sMessage, NULL, MB_ICONERROR);
      return;
   }
mesajflaviu
Membru++
Membru++
 
Mesaje: 681
Membru din: 10 Sep 2008, 21:40
Judet: Cluj


Înapoi la Windows API

Cine este conectat

Utilizatorii ce navighează pe acest forum: Niciun utilizator înregistrat şi 3 vizitatori

cron