C++ 如何从失败(HRESULT)引发std::system_错误异常?
这是正常的Win32错误,可以自动检索错误描述,并且工作得非常好:C++ 如何从失败(HRESULT)引发std::system_错误异常?,c++,winapi,exception,com,throw,C++,Winapi,Exception,Com,Throw,这是正常的Win32错误,可以自动检索错误描述,并且工作得非常好: if (!SomeWinFunc()) { throw std::system_error(GetLastError(), std::system_category(), "SomeWinFunc crashed badly"); } 但是,我不确定如何处理COM错误,检查如下: HRESULT hr = comObj->SomeFunc(); if (FAILED(hr)) { throw st
if (!SomeWinFunc()) {
throw std::system_error(GetLastError(),
std::system_category(),
"SomeWinFunc crashed badly");
}
但是,我不确定如何处理COM错误,检查如下:
HRESULT hr = comObj->SomeFunc();
if (FAILED(hr)) {
throw std::system_error(hr, // <-- is it correct here?
std::system_category(),
"SomeFunc crashed right now");
}
HRESULT hr=comObj->SomeFunc();
如果(失败(小时)){
抛出std::system_error(hr,//通常,我使用Microsoft标准的\u com_error
异常类型来处理此问题,可以通过以下操作之一轻松引发此异常
_com_util::CheckError(hr); // throws when FAILED(hr)
_com_issue_error(hr); // throws always
Win32错误可以转换为HRESULT
,如下所示:
hr = HRESULT_FROM_WIN32(GetLastError());
但是,这意味着您必须处理一个新的异常类型,这可能会有问题。要用纯STL的方式来处理,我认为您需要派生一个新的错误\u类别
,并使用它来代替系统\u类别
。我将查看
标题并复制系统\u类别
的实现,更新根据需要为HRESULT
s初始化
理想情况下,HRESULT
中的差异将由不同的error\u category
实现提供服务——这样做将非常有效地传达异常及其源代码。但这是一个棘手的问题,您可能只需要处理HRESULT
的单个com\u类别
重要的是要注意,当使用std::system_类别
作为上下文时,不能传递HRESULT
。该类别用于GetLastError
返回的错误代码。例如,如果传递COM成功代码s_FALSE
,则会被解释为error\u INVALID\u函数
。有关如何实现自定义错误\u类别的信息,请访问。@IInspectableS\u FALSE
不是一个好例子,因为它不是错误代码。因此没有理由抛出它。HRESULT
可以表示的错误值与GetLastError返回的错误代码不重叠
,因为HRESULT
错误总是负面的。因此,在我看来,HRESULT
不需要特殊类别,只要您只抛出失败(hr)的值==true
@zett42:这取决于您的代码逻辑。成功的COM调用可能会产生一个条件,您无法从中恢复,需要抛出。即使不是这样,您仍然需要一个自定义错误类别来生成错误消息。虽然FormatMessage
可以与系统定义的HRESULT
值一起使用,但是在处理客户定义的代码时,看起来会有所不同。您需要其他信息来将这些信息转换为错误消息,即模块句柄。这需要在类别中进行编码,因为您无法将其他信息与错误代码一起传递。找到了为HRESU创建专用错误类别的另一个原因LT
:能够以通用的方式检查错误代码。例如,以下操作不起作用:std::error\u code E(HRESULT\u来自WIN32(error\u FILE\u NOT\u FOUND),std::system\u category());if(E==std::errc::no\u这样的文件或目录){/*执行某些操作*/}
。这可以通过覆盖std::error\u category::default error\u条件()
在派生类中。你有什么进展吗?@MichaelGunter,我仍然没有实现100%正确的解决方案(可能从你的代码开始),但由于我的需要只是处理系统COM对象,所以我在问题中编写的方法很有效,我运行了几个测试。我计划一有时间就深入研究这个问题。