2

如果您有一个大型系统,它会自动显示一个漂亮的窗口来解释捕获的异常,那么能够将错误代码与消息一起显示会很好(以供进一步调查)。但是由于某些函数调用是针对设置错误代码的失败 Windows 函数,而有些是未设置错误代码的本地失败函数,我想知道是否有办法检查最后设置的错误代码是否已“检索” “ 已经。

假设我们有一段代码

if (!CopyFile(("c:\foobar.txt", "d:\foobar.txt",FALSE))
{
  throw FooBarException("bla bla bla");
}

在这里可以自动将错误代码添加到错误消息中,因为 CopyFile 是一个在失败时设置错误代码的函数。现在,我们可以在 if 语句中“手动”添加错误代码,并将其附加到创建异常时传递的错误字符串中。但是为了不必更改现有代码中的数千个位置,我们可以让FooBarException的构造函数自动获取并附加错误代码。但这也提出了有问题的问题。

如果某些未设置错误代码的代码导致引发FooBarException 怎么办。然后构造函数将GetLastError但得到一个可能根本没有连接到当前异常的错误代码。

但是,如果FooBarException的构造函数可以调用一些LastErrorRetrived(或类似的东西)并且如果在它应该忽略附加错误代码并假设它连接到更早的错误之前已经检索到错误代码并获得true 。

现在我明白了,如果在每个可能失败并设置错误代码的 Windows 函数之后实际上没有“检索”错误代码,这可能会变得混乱。但是让我们假设这已经完成。

4

2 回答 2

2

简短的回答:没有。

返回的值GetLastError只是一个没有附加任何逻辑的全局(每个线程)对象。它可以通过GetLastErrorSetLastError而且神秘RestoreLastError

恐怕我不得不爆料:将错误处理改造成一个没有准备好的系统是乏味的。

HRESULT除了实现几个异常类(对于 Win32 错误代码、COM等)和更改每个调用之外,您几乎无能为力。

于 2013-09-17T11:31:19.187 回答
1

GetLastError() 只是获取线程的最后一个错误代码值,仅此而已。所以,我相信没有办法知道它是被调用一次还是被调用了几次。此外,我真的不认为你需要。

这里最好的解决方案是创建从某个基类(例如std::exception )派生的WinAPIException类。在构造函数中, WinAPIException应该在任何其他 WinAPI 调用之前调用 GetLastError()。它保证错误值不会改变。

if( !CopyFile("c:\foobar.txt", "d:\foobar.txt",FALSE) )
    throw WinAPIException("Houston, we have a WINAPI problem");

如果您在非 WinAPI 函数调用后检查结果 - 只需使用其他异常类(派生自同一基类):

if( std::cin.get() < 0 )
    throw std::runtime_error("Houston, we have runtime problem");

因此,您可以使用单个 try...catch 语句来捕获这两个异常:

try {
    ...
} catch( std::exception &e ) {
    ...
}
于 2013-09-17T11:24:02.970 回答