報告錯誤以及有關失敗的其他資訊

除了失敗/成功返回值之外,某些 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 中)返回三個值:r1r2errr2 從未使用過; 你可以在那裡使用空白識別符號。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