是否可以使用GetLastError检查错误代码是否已恢复



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

假设我们有一段代码

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

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

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

但是,如果 FooBarException 的构造函数可以调用一些 LastErrorRetrived(或类似的东西)并且如果错误代码在它之前已经被检索到,则忽略附加错误代码并假设它与早期错误有关。

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

简短回答:不。

GetLastError返回的值只是一个全局(每线程)对象,不附加任何逻辑。它可以通过GetLastErrorSetLastError和神秘的RestoreLastError进入。

恐怕我必须爆料:将错误处理改装到一个没有准备好的系统中是乏味的。

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

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

这里最好的解决方案是创建从某个基类派生的WinAPIException类(例如,std::exception)。在构造函数中,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");

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

try {
    ...
} catch( std::exception &e ) {
    ...
}

最新更新