如何使用std::system_error和GetLastError?

18
如果我调用一个通过GetLastError报告错误的Win32函数,例如RegisterClassEx,我该如何为该错误抛出std::system_error?
2个回答

20

请检查GetLastError()函数的返回值,例如:

DWORD dwErrVal = GetLastError();
std::error_code ec (dwErrVal, std::system_category());
throw std::system_error(ec, "Exception occurred");

点击此处可查看error_code,点击此处可查看std::system_error


嗯,这似乎对我不起作用。 GetLastError() 返回 ERROR_INVALID_PARAMETER,但 system_error::what 只是说“未知错误”。 - Mooing Duck
system_error是用于errno代码,而不是Win32代码。它们是不同的。http://newscentral.exsees.com/item/d33ca604e6a55888937840570a5cd17d-76c1546f7ca7c2c00921bccdb34ec2d1 - Mooing Duck
@MooingDuck 我认为msvc的system_category实现确实是为了GetLastError()返回的代码而设计的,但它只针对所有代码的一小部分返回适当的消息 - 至少在VS2013中是这样的 - 而ERROR_INVALID_PARAMETER不是其中之一。请参见crt源代码中syserror.cpp中的_Winerror_map。 - stijn
1
在Win32平台上实现C++11中的整个std::system_category()是一场灾难。请查看**这里**。标准基本上没有为同时具有errno和本地错误代码的系统提供任何规定。 - rustyx
@RustyX 不是这样的。系统错误代码应该与 system_category 一起使用,并且它将与 std::errc 常量相当。如果使用 Visual C++ 2015 或更高版本(在您发表评论时可用),那么 std::error_code(ERROR_FILE_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory 是正确的。 - Yongwei Wu
显示剩余4条评论

9
请注意,如果你的供应商不同,比较在std::system_category()类别中的std::error_code通常无法与std::errc枚举常量配合使用。例如: std::error_code(ERROR_FILE_NOT_FOUND, std::system_category()) != std::errc::no_such_file_or_directory) 某些供应商需要使用std::generic_category()才能正常工作。
在MinGW中,std::error_code(ERROR_FILE_NOT_FOUND, std::system_category()).message()将无法给出正确的消息。
为了实现真正便携和强大的解决方案,我建议将std::system_errorstd::system_category子类化为windows_errorwindows_category并自行实现正确的功能。YMMV,据报告,VS2017可以按预期工作。

2
有人肯定已经做过这个了,对吧?但是我找不到 :( - Mooing Duck
我是在2017年写的,所以我有很大的优势。然而,你的回答存在几个问题。你的第一个例子失败的原因是因为你应该使用ERROR_FILE_NOT_FOUND。其次,即使在Visual C++ 2017(但不是2013)下,即使你使用system_categoryERROR_PATH_NOT_FOUND也可以工作。是的,只有当使用system_category而不是generic_category时才能正常工作,微软已经做得非常好了。 - Yongwei Wu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接