2012-04-16 21 views
3

は、何らかのエラーが発生したとき、人は次のことを行う必要があり、典型的なCOMの手順に従ってください:C++でCOMを呼び出すと、どのようにエラーをラップしますか?

  1. チェックFAILEDまたは類似とHRESULT、エラーが発生したかどうかを確認します。
  2. IErrorInfo(通常CComPtr<IErrorInfo>
  3. コール::GetErrorInfo(0, &var)を保持する変数を作成します。
  4. Get the human readable version of that by calling IErrorInfo::GetDescription.
  5. std::wstringに変換します。
  6. std::wstringchar const*の形式に変換します。
  7. std::exceptionから派生し、上記のビット1,5、および6を公開するユーザー定義の例外タイプをスローします。

これは、すべてCOMのほぼすべての関数呼び出しの周りを移動しなければならない定型文のようです。

私はMSVC++コンパイラが、ATLやコンパイラ固有のCOM拡張子_com_error_com_raise_errorなどのようなCOMを使いこなすのを簡単にするためにたくさんのものを提供していることは知っていますが、それらがユーザコードによって使用されることさえ意図されていれば。

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

+1

#importディレクティブで始まり、残りは自動的に所定の場所に落ちます。 –

+0

@HansPassant:対象のタイプライブラリがありません。 (私が持っているのは 'wbemidl.h'です) –

+1

次にfuggedaboudid、あなたはあなた自身でそれをラップする必要があります。 CheckHR()関数を書くだけです。 –

答えて

4

"わかりやすい"解決策はComExceptionです。これはかなりのすべてのステップを処理することができます - あなたはHRESULTをctorに取得し、結果オブジェクトをスローする必要があります(ステップ1と7)。

あなたも、あなたのためのステップ7の世話をするために

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

を書くことができます。例えば。 check(pUnk->QueryInterface(MyID, &pMyIf));

+0

これはIErrorInfo –

+0

@AlexandreCを照会しません。 :それは 'ComException :: ComException(HRESULT)'で起こります。 – MSalters

+0

ComExceptionはどのようにしてIErrorInfoへのポインタを取得しますか?何らかの理由で、最初に関数を呼び出すインターフェイスへのポインタを渡す必要がありますか? @AlexandreC。 –

1

msdnのサンプルアプリケーションとAPIの使用状況を見ても、手動ですべての退屈なHResultチェックを実行して、 IPtrは有効です。あなたはコードを複製しないように、これをすべてラップする独自の関数を書く必要があります。問題ではありません。

関連する問題