C++ 在C++;?

C++ 在C++;?,c++,windows,visual-c++,com,error-handling,C++,Windows,Visual C++,Com,Error Handling,要遵循典型的COM过程,每当发生任何错误时,必须执行以下操作: 检查HRESULT和FAILED或类似项,查看是否发生错误 创建一个变量来保存IErrorInfo(通常是CComPtr) 调用::GetErrorInfo(0,&var) 将BSTR转换为std::wstring 将std::wstring转换为某种形式的char const* 抛出一个用户定义的异常类型,该异常类型派生自std::exception,它公开上面的位1、5和6 这看起来像是很多样板文件,在COM中几乎每个函数调用

要遵循典型的COM过程,每当发生任何错误时,必须执行以下操作:

  • 检查
    HRESULT
    FAILED
    或类似项,查看是否发生错误
  • 创建一个变量来保存
    IErrorInfo
    (通常是
    CComPtr
  • 调用
    ::GetErrorInfo(0,&var)
  • BSTR
    转换为
    std::wstring
  • std::wstring
    转换为某种形式的
    char const*
  • 抛出一个用户定义的异常类型,该异常类型派生自
    std::exception
    ,它公开上面的位1、5和6
  • 这看起来像是很多样板文件,在COM中几乎每个函数调用都要用到

    我知道MSVC++编译器提供了一大堆东西来简化COM,比如ATL,以及编译器特定的COM扩展
    \u COM\u error
    \u COM\u raise\u error
    和类似的东西,但我不确定如何使用它们,或者它们是否打算由用户代码使用


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

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

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

    你甚至可以写

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

    为您完成第7步。例如,
    check(朋克->查询接口(MyID和pMyIf))

    从#import指令开始,其余的自动就位。@HansPassant:我没有相关目标的类型库。(我只有
    wbemidl.h
    )然后Fuggedaboudi,你必须自己包装它。只需编写一个CheckHR()函数。@HansPassant:是的,我自己就可以轻松地完成它;但是,如果已经有一种半标准的方法在使用大量COM的人中实现这一点,我想用典型的方法来实现,而不是发明新的东西。为什么要执行第6步<代码>标准::异常
    不需要
    常量字符*
    @AlexandreC.:这将发生在
    ComException::ComException(HRESULT)
    中。ComException如何检索指向IErrorInfo的指针?您必须以某种方式向它传递一个指针,指向最初调用函数的接口,否?@AlexandreC.:不