Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从失败(HRESULT)引发std::system_错误异常?_C++_Winapi_Exception_Com_Throw - Fatal编程技术网

C++ 如何从失败(HRESULT)引发std::system_错误异常?

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

这是正常的Win32错误,可以自动检索错误描述,并且工作得非常好:

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类别的信息,请访问。@IInspectable
S\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对象,所以我在问题中编写的方法很有效,我运行了几个测试。我计划一有时间就深入研究这个问题。