2015-11-02 63 views
0

我知道GetLastError將在錯誤發生時立即被調用。我寫的函數:我可以在我的函數的第一行啓動`GetLastError`嗎?

void PrintErrorMsg() { 
    DWORD errCode = GetLastError(); 
    LPTSTR msg = NULL; 
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
     NULL, errCode, 0, (LPTSTR)&msg, 0, NULL); 
    wcerr << msg << endl; 
    HeapFree(GetProcessHeap(), 0, msg); 
} 

現在我用它在我的代碼:

LPCTSTR boundaryName = L"BushmanBoundary"; 
HANDLE hBoundary = CreateBoundaryDescriptor(boundaryName, 0); 
if (NULL == hBoundary) { 
    PrintErrorMsg(); 
} 

所以我的第一個代碼行稱爲GetLastErrorPrintErrorMsg函數內。這種使用方式是否可以接受?

+0

只要你不調用影響錯誤條件的其他Windows API函數,那麼你應該沒問題。 – PaulMcKenzie

+3

我會將錯誤代碼作爲參數提供給'PrintErrorMsg',並讓調用者在適當的時候調用GetLastError。這使得在你所做的調用和PrintErrorMsg()之間的無代碼「滑入」更明顯和更安全。 –

+0

是@ Christian.K,我也是。但是*沒有任何參數的情況下的行爲*對我來說也很有趣。 –

回答

1

調用線程執行的函數通過調用SetLastError函數來設置此值。當函數的返回值指示這樣的調用將返回有用的數據時,應立即調用GetLastError函數。這是因爲一些函數在成功時調用SetLastError,並清除由最近失敗的函數設置的錯誤代碼。

你的代碼是好的,因爲你不是在調用可能失敗和您的來電GetLastError()之間調用SetLastError()的功能(如Win32 API調用)。

請記住,插入運算符可以調用SetLastError()

std::cout << "Win32 function failed with error: " << GetLastError() << std::endl; 

我已經在過去的地方,因爲它已被插入運營商設置/復位GetLastError()不會返回正確的錯誤代碼是這樣的抓了出來。

2

該代碼很好。在CreateBoundaryDescriptor返回和您撥打GetLastError之間不會調用Windows API函數。

0

是的,這是允許的。我做了類似的事情,但我作爲一個參數傳遞錯誤代碼,但要對參數的默認值GetLastError()的結果,就像這樣:

// in header file 
void PrintErrorMsg(DWORD errCode = GetLastError()); 


// in implementation file 
void PrintErrorMsg(DWORD errCode ) 
{ 
    // ... 
} 

它更靈活,工作非常出色爲了我。

0

我發現處理這些Win32 API(或任何C風格API)的低級細節的最好方法是立即將該C風格API儘快升級到C++實踐。我使用的一種方法是將C風格的API調用封裝在驗證返回值的宏中,然後在返回值指示失敗時將相應的錯誤代碼提取到異常中。

Chapter 1我的書"The Direct3D Graphics Pipeline"概述了這種方法用於COM HRESULT的返回值。如果HRESULT指示失敗,則會引發宏THR。在HRESULT中,故障狀態和錯誤代碼包含在相同的積分值中,因此可以通過提供的HRESULT直接計算異常。在將要檢查的值傳遞給檢查失敗的輔助函數之前,該宏使用__FILE____LINE__修飾參數。如果檢測到故障,所有信息將被收集到一個拋出的異常中。如果HRESULT指示成功,則返回HRESULT值。

我還爲TWS提供了Win32 API狀態的類似變體。這將對Win32 API進行必要的驗證檢查(通常是與FALSE0進行比較的某個版本),如果失敗,則立即調用::GetLastError()以獲取異常的錯誤代碼。

在這兩種情況下,我都嘗試使用::FormatMessage在構建將拋出的異常值時獲取有意義的錯誤消息字符串。

這些宏旨在用於您不希望API調用失敗並且失敗確實非常特殊的情況。

相關問題