3

通常のCOM手順に従うには、エラーが発生するたびに、次のことを行う必要があります。

  1. HRESULTwithまたは同様のものをチェックしてFAILED、エラーが発生したかどうかを確認します。
  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 ++コンパイラは、ATLやコンパイラ固有のCOM拡張機能など、COMを簡単に操作できるようにするためのさまざまな機能を提供していることは知っていますが_com_error_com_raise_errorこれらの使用方法や、意図されているかどうかはわかりません。ユーザーコードで使用されます。

例外安全で競合状態の安全な方法でこの複雑さを管理するために使用される典型的な戦略はありますか?

4

2 に答える 2

4

「明らかな」解決策はComExceptionです。ほぼすべてのステップを処理できます。ctorのを取得してHRESULT、結果のオブジェクトをスローするだけです(ステップ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 に答える