2015-11-02 62 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调用失败并且失败确实非常特殊的情况。

相关问题