2017-04-06 43 views
3

雖然調用Windows API函數封裝一樣ExtractShortPathName後使用GetLastError我注意到,GetLastError不管調用ExtractShortPathName是成功還是失敗返回非零錯誤代碼。實際上,在我的程序執行之前,似乎有一個「最後的錯誤」,例如,爲什麼GetLastError在我的程序開始之前有錯誤?

program TestGetLastError; 

{$APPTYPE CONSOLE} 
{$R *.res} 

uses 
    System.SysUtils; 

var 
    ErrorCode: Integer; 

begin 
    try 
    ErrorCode := GetLastError; 
    if ErrorCode <> 0 then 
     RaiseLastOSError; 
    except 
    on E: Exception do 
     WriteLn(E.ClassName, ': ', E.Message); 
    end; 
end. 

結果:

EOSError: System Error. Code: 122. 
The data area passed to a system call is too small 

我誤解的東西或者做錯了什麼?

如果Delphi運行時正在做某些事情導致GetLastError被設置,那麼在我的程序開始執行之前清除該錯誤的正確方法是什麼?我應該使用SetLastError(ERROR_SUCCESS);這樣的例子來自德爾福API文檔:

procedure TForm2.btRaiseLastClick(Sender: TObject); 
begin 
    { Set the last OS error to a bogus value. } 
    System.SetLastError(ERROR_ACCESS_DENIED); 

    try 
    RaiseLastOSError(); 
    except 
    on Ex : EOSError do 
     MessageDlg('Caught an OS error with code: ' + IntToStr(Ex.ErrorCode), mtError, [mbOK], 0); 
    end; 

    { Let the Delphi Exception dialog appear. } 
    RaiseLastOSError(ERROR_NOT_ENOUGH_MEMORY); 

    { Finally set the last error to none. } 
    System.SetLastError(ERROR_SUCCESS); 

    if GetLastError() <> ERROR_SUCCESS then 
    MessageDlg('Whoops, something went wrong in the mean time!', mtError, [mbOK], 0); 

    { No exception should be thrown here because last OS error is "ERROR_SUCCESS". } 
    CheckOSError(GetLastError()); 
end; 

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/LastOSError_(Delphi)

+5

除非出現問題,否則不要調用GetLastError。這沒有意義。 –

+1

我有完全相同的結果。有趣的是,當我從uses子句(以及所有需要的)中刪除'SysUtils'時,我得到錯誤代碼'50'('請求不支持')。但@喬納森的權利,沒有理由調用'GetLastError',除非實際發生錯誤。想象一下10分鐘前在完全不同的窗口中發生的錯誤。然後,無論出於何種原因,您調用'GetLastError',從而從10分鐘前返回相同的代碼。 –

+3

API文檔指出,只有在a)API調用失敗時才使用GetLastError,以及b)失敗的函數表示可以使用GetLastError獲取有關原因的更多信息。隨機地調用它或調用它而沒有記錄失敗的功能是沒有意義的。除非知道發生了錯誤,否則不能調用GetLastError,並且只有在您調用的特定函數指示失敗後才調用GetLastError。 –

回答

4

GetLastError的文件表明,只有用的,如果

  • 的API調用失敗,並
  • 失敗的功能表示可以使用GetLastError關於爲什麼越來越多的信息。 從這個文檔(重點煤礦

返回值是調用線程的最後錯誤代碼。

設置最後一個錯誤代碼的每個函數的文檔的返回值部分指出函數設置最後錯誤代碼的條件。設置線程最後錯誤代碼的大多數函數在失敗時設置它。但是,一些函數在成功時也會設置最後的錯誤代碼。 如果該函數沒有記錄來設置最後的錯誤代碼,則此函數返回的值僅僅是最近設置的最後一個錯誤代碼;一些函數在成功時將最後的錯誤代碼設置爲0,而其他函數則不會。

這表明,調用它時沒有首先在記錄失敗時設置失敗是沒有意義的。除非知道發生了錯誤,否則不能調用GetLastError,並且只有在您調用的特定函數指示失敗後才調用GetLastError。

13

通過GetLastError()返回的值是唯一相關的是,失敗的Windows API的調用,並在那裏爲函數指定的文件後,立即通過調用GetLastError()可獲得擴展錯誤信息。

調用它這方面之外將從先前調用,這可能是從你的代碼,德爾福運行時,你已經叫,甚至一些Windows API中的DLL返回的東西...

由於爲GetLastError()狀態Windows的API文檔:

你應該立即撥打GetLastError函數時 函數的返回值表示,這樣的調用將返回有用 數據。

相關問題