例外をスローする既存のネイティブ クラスの .NET ラッパー クラスを作成しています。ネイティブ C++ 例外とマネージ例外を変換するためのベスト プラクティスは何ですか? 1 対 1 でキャッチして再スローしますか (例: std::invalid_argument -> System.System.ArgumentException)? すでにどこかにマッピングが作成されていますか?
4 に答える
私が知っている標準的なマッピングはありません。私が過去に行ったことは、私が知っているものと、System.Runtime.InteropServices.SEHException の catch ブロックを翻訳することです。翻訳されていないすべての例外は、その例外に変換されます。例外をスローしているコードのデバッグ ビルドがある限り、適切なスタック トレースが得られるはずです。次に、例外を確認してラッパーを記述します。
しかし、これを行う必要があった最後のプロジェクトでは、もっと単純なものを使用して、logic_error と runtime_error の System.Exception 派生物をいくつか作成しました。次に、これら 2 つの基本クラスをキャッチし、typeid(err) を使用して、スローされた .NET メッセージを書き込みます。このようにして、C++ からスローされたものを「失う」ことはありませんでしたが、最も重要なものを除いてすべてをマップする必要はありませんでした。
ラッパーのデザインによると思います。マネージャー ラッパーのインターフェイスがアンマネージ ライブラリのインターフェイスとほぼ同じになる場合は、例外を 1:1 で再スローします。インターフェイスを大幅に変更する場合は、新しいインターフェイスに最も適した例外をスローします。いずれにせよ、.NET 設計ガイドラインとの一貫性を保つために、操作を完了できない場合はいつでもラッパーが例外をスローするようにしてください。
1 対 1 のマッピングは、私にとって最も健全なアプローチのように思えます。アプリケーション固有の例外のため、「ユニバーサル」マッピングはほとんど不可能ですが、STL 例外クラスには明らかなマッピングがいくつかあります。
また、アンマネージ コードからの SEH 例外の問題もあります。状況によっては、それらをキャッチしてラップする必要がある場合もあります。
あなたは本当に何をしようとしていますか?
Interop は、SEH 例外を含む、ネイティブ例外をマネージド例外に既に変換しています。ただし、優れた設計では、すべての例外をネイティブ API レベルでキャッチする必要があります。正当な理由がない限り、これを逸脱してはなりません。私たちはあなたのデザインについて十分に知りません。