2017-12-06 64 views
1

これは、自動的にエラーの説明を取得し、正しくhow to throw通常のWin32エラーであり、それはうまく見事に動作します:FAILED(HRESULT)からstd :: system_error例外をスローする方法はありますか?

if (!SomeWinFunc()) { 
    throw std::system_error(GetLastError(), 
    std::system_category(), 
    "SomeWinFunc crashed badly"); 
} 

しかし、私はこのようなidiomaticallyをチェックされたCOMエラーに対処する方法については不確かです。

HRESULT hr = comObj->SomeFunc(); 
if (FAILED(hr)) { 
    throw std::system_error(hr, // <-- is it correct here? 
    std::system_category(), 
    "SomeFunc crashed right now"); 
} 

それは、HRESULTsystem_errorに渡す正しいです、またはCOM関数から例外をスローする別の方法は何ですか?

+0

これでどこにいらっしゃいましたか? –

+0

@MichaelGunter、私はまだ100%正しい解決策(あなたのコードで始まっているかもしれません)を実装していませんでしたが、私のニーズはシステムCOMオブジェクトを扱っているだけなので、質問に書いたアプローチはうまくいく。私は時間を見つけたら直ちにこれを深くするつもりです。 – Rodrigo

答えて

3

通常、これはMicrosoft標準の_com_error例外タイプを使用して処理されますが、これは次のいずれかによって容易に引き上げることができます。

_com_util::CheckError(hr); // throws when FAILED(hr) 
_com_issue_error(hr); // throws always 

A Win32エラーがそうのようなHRESULTに変換することができます。

hr = HRESULT_FROM_WIN32(GetLastError()); 

しかし、これはあなたが問題となり得る新しい例外型、に対処する必要があることを意味します。これを行うには、純粋なSTLの方法、私はあなたが新しいerror_categoryを派生し、system_categoryの代わりにそれを使用する必要があると思う。私は<system_error>ヘッダーを見て、HRESULTのために必要に応じて更新するsystem_categoryの実装をコピーします。

HRESULTの異なるfacility codesは異なるerror_categoryの実装によって提供されることが理想的です。これにより、例外とそのソースが非常に効果的に通信されます。しかし、それは難しいです。HRESULTを一般的に扱う1つのcom_categoryを手に入れることができます。

+0

コンテキストとして 'std :: system_category'を使用するときに** HRESULTを渡すべきではないことに注意してください。このカテゴリは、 'GetLastError'によって返されたエラーコードでの使用を意図しています。たとえば、COM成功コード 'S_FALSE'を渡すと、' ERROR_INVALID_FUNCTION'と解釈されます。あなたのカスタム 'error_category'の実装方法に関する情報は、[C++ 0x - part 4のシステムエラーサポート](http://blog.think-async.com/2010/04/system-error-support- in-c0x-part-4.html)を参照してください。 – IInspectable

+1

@IInspectable 'S_FALSE'はエラーコードではないので、良い例ではありません。だから、それを投げる理由はありません。 'HRESULT'エラーは常に負であるため、' HRESULT'が表すことができる*エラー*値は 'GetLastError'によって返されるエラーコードと重複しません。だから私の意見では、 'HRESULT'の特別なカテゴリは' FAILED(hr)== true'の値を投げるだけで長く必要なわけではありません。 – zett42

+0

@ zett42:それはあなたのコードロジックに依存します。成功したCOM呼び出しは、回復できず、スローする必要がある条件を生成できます。そうでない場合でも、エラーメッセージを生成するためにカスタムエラーカテゴリが必要です。 'FormatMessage'はシステム定義の' HRESULT'値と一緒に使うことができますが、顧客が定義したコードを扱うときには異なって見えます。それらをエラーメッセージ、つまりモジュールハンドルに変換するには、追加情報が必要です。エラーコードの横に追加の情報を渡すことはできないため、そのカテゴリでコード化する必要があります。 – IInspectable

関連する問題