3

要遵循典型的 COM 程序,无论何时发生任何错误,都必须执行以下操作:

  1. 检查HRESULTwithFAILED或类似,以查看是否发生错误。
  2. 创建一个变量来保存IErrorInfo(通常CComPtr<IErrorInfo>
  3. 打电话::GetErrorInfo(0, &var)
  4. 通过调用IErrorInfo::GetDescription.
  5. 将 转换BSTRstd::wstring.
  6. 将 转换std::wstring为某种形式的char const*.
  7. 抛出一个用户定义的异常类型,该类型派生出std::exception上述第 1、5 和 6 位。

这一切看起来像是很多样板文件,几乎必须绕过 COM 中的每个函数调用。

我知道 MSVC++ 编译器提供了一大堆东西来让 COM 更容易搞乱,例如 ATL,以及编译器特定的 COM 扩展_com_error_com_raise_error,但我不知道如何使用这些,或者它们是否是有意的供用户代码使用。

是否有任何典型的策略用于以异常安全和竞争条件安全的方式管理这种复杂性?

4

2 回答 2

4

“显而易见”的解决方案是ComException. 它几乎可以处理所有步骤 - 您只需要获取HRESULTctor 并抛出结果对象(步骤 1 和 7)。

你甚至可以写

HRESULT check(HRESULT hr)
{
  if(FAILED(hr)) throw ComException(hr);
  return hr; // Success comes in different forms. 
}

为您完成第 7 步。例如check(pUnk->QueryInterface(MyID, &pMyIf));

于 2012-04-16T08:28:27.253 回答
1

恐怕没有为您提供半标准的方式,即使您查看 msdn 上的示例应用程序和 api 使用情况,它们都表明您必须手动进行所有繁琐的 HResult 检查,检查 IPtr 是否有效等等。你必须编写自己的函数来包装所有这些,这样你就不会重复代码,这应该不是问题。

于 2012-04-16T07:04:48.983 回答