報告錯誤以及有關失敗的其他資訊
除了失敗/成功返回值之外,某些 API 呼叫還會設定失敗時的最後一個錯誤(例如 CreateWindow )。該文件通常包含以下標準措辭:
如果函式成功,則返回值為 <API 特定的成功值> 。
如果函式失敗,則返回值為 <API 特定的錯誤值> 。要獲取擴充套件錯誤資訊,請呼叫 GetLastError 。
if ( CreateWindowW( ... ) == NULL ) {
// Failure: get additional information.
DWORD dwError = GetLastError();
} else {
// Success: must not call GetLastError.
}
**至關重要的是你立即致電 GetLastError()
。**最後一個錯誤程式碼可以被任何其他函式覆蓋,因此如果在失敗的函式和對 GetLastError()
的呼叫之間有額外的函式呼叫,則 GetLastError()
的返回將不再可靠。處理 C++建構函式時要格外小心。
獲得錯誤程式碼後,你需要解釋它。你可以在系統錯誤程式碼(Windows)頁面上獲得 MSDN 上的錯誤程式碼的完整列表。或者,你可以檢視系統標頭檔案; 所有錯誤程式碼常量的檔案是 winerror.h
。 (如果你使用的是適用於 Windows 8 或更高版本的 Microsoft 官方 SDK,則它位於 include 資料夾的 shared
子資料夾中。)
關於在其他程式語言中呼叫 GetLastError()
的注意事項
.net 語言(C#,VB 等)
使用 .net,你不應該直接 P / Invoke 到 GetLastError()
。這是因為 .net 執行時將在你背後的同一個執行緒上進行其他 Windows API 呼叫。例如,如果垃圾收集器找到了不再使用的足夠記憶體,則可能會呼叫 VirtualFree()
,這可能發生在你的預期函式呼叫和你對 GetLastError()
的呼叫之間。
相反,.net 提供了 Marshal.GetLastWin32Error()
函式,它將從你自己進行的上一次 P / Invoke 呼叫中檢索最後一個錯誤。使用此代替直接呼叫 GetLastError()
。
(.net 似乎並沒有阻止你匯入 GetLastError()
;我不知道為什麼。)
走
Go 提供的用於呼叫 DLL 函式的各種工具(位於包 syscall
和 package golang.org/x/sys/windows
中)返回三個值:r1
,r2
和 err
。r2
從未使用過; 你可以在那裡使用空白識別符號。r1
是函式的返回值。err
是呼叫 GetLastError()
的結果,但轉換為實現 error
的型別,因此你可以將其傳遞給呼叫函式來處理。
因為 Go 不知道何時呼叫 GetLastError()
而不知道何時呼叫 GetLastError()
,它將始終返回非 nil
錯誤。因此,典型的 Go 錯誤處理成語
r1, _, err := syscall.Syscall12(CreateWindowW.Addr(), ...)
if err != nil {
// handle err
}
// use r1
不管用。相反,你必須檢查 r1
,就像你在 C 中一樣,並且如果這表明函式返回了錯誤,則只使用 err
:
r1, _, err := syscall.Syscall12(CreateWindowW.Addr(), ...)
if r1 == 0 {
// handle err
}
// use r1