標籤:style blog http io ar color os 使用 sp
在多數情況下,windows API在發生錯誤時很少拋出異常,多數是通過函數傳回值進行處理。(windows api中無傳回值的函數很少。)
windows api錯誤處理通常按照以下方式:首先api函數返回特殊的值,表明函數內部發生錯誤;然後調用方可以使用GetLastError獲得對應的錯誤碼。
通常情況下windows api按照傳回型別可以分為以下幾類:
- 傳回值為BOOL類型。有錯誤發生,傳回值為0,否則返回非零值。
- 傳回值為HANDLE類型。有錯誤發生時,返回NULL或INVALID_HANDLE_VALUE(值為-1)。
- 傳回值為LONG類型或DWORD類型。有錯誤發生時,返回0或-1。
由於windows api傳回型別不太一致,所以在實際處理windows api錯誤時建議查看下msdn上對應的說明,並按照其中的解釋處理對應的錯誤碼。
DWORD WINAPI GetLastError(void);
通過調用GetLastError函數返回的錯誤碼是一個DWORD類型(32bit),其固定位域映射格式如下(按照windows下小端位順序,從低位到高位依次編號0,1,…,30,31;注意下表中都是按照位元據表示的):
位 |
含義 |
bit30~31 |
安全層級,00=安全,01=資訊,10=警告,11=錯誤 |
bit29 |
錯誤來源,0-Microsoft定義的,1-使用者自訂錯誤碼 |
bit28 |
保留位,必須是0 |
bit16~27 |
錯誤來源的工具碼,Microsoft定義的(Winerror.h) |
bit0~15 |
工具對應的狀態代碼,Microsoft或使用者定義。 |
如果需要的話,我們也可以自己定義錯誤碼,並使用windows api類似的錯誤機制,具體可參考 SetLastError 、 SetLastErrorEx函數,但需要注意自訂的錯誤碼不要跟windows錯誤碼重複。
查看錯誤碼對應的資訊可以使用visual c++提供的錯誤尋找工具(Error Lookup Tool),也可以直接在調試器的觀察視窗中輸入“@err, hr”。
當然也可以使用FormatMessage函數將錯誤碼直接轉化成對應的字串。調用代碼如下:
// Windows錯誤碼解析程式,ErrCodeParseDemo// 簡單介紹如何將錯誤碼轉化為對應的字串資訊// 建議使用vs2005以上版本編譯 unicode編碼#include <windows.h> #include <iostream>#include <WinError.h>using std::wcout;using std::endl;void OutputFormatMessage(DWORD errCode){ LPTSTR lpMsgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); wcout << "err:" << std::hex << errCode << " Msg tips:" << endl << lpMsgBuf << endl; LocalFree(lpMsgBuf);}int _tmain(int argc, _TCHAR* argv[]){ // 輸出中文 std::wcout.imbue(std::locale("chs")); // 設定控制台標題列 SetConsoleTitle(TEXT("ErrCodeParseDemo")); OutputFormatMessage(ERROR_INVALID_FUNCTION); OutputFormatMessage(ERROR_HANDLE_EOF); return 0; }
View Code
上述代碼可從[email protected]下載,連結如下:https://git.oschina.net/Tocy/SampleCode.git。位於ErrCodeParseDemo.cpp中。
Windows API 錯誤碼