7

No(フラグが指定されていない)にEnable C++ Exceptions設定されたサードパーティの静的ライブラリが構築されています。C ++例外を有効にしてビルドされたコードから呼び出すとどうなりますか()?ライブラリ内から構造化例外がスローされた場合、メインアプリケーションによって_set_se_translatorに提供された関数は確実に呼び出されますか?(私の実験ではそうなることが示されていますが、これが定義された動作であるかどうか疑問に思っています)。/EH/EHa

/EH例外処理モデルを混合する際に他に考慮すべき点はありますか?

4

2 に答える 2

5

例外が有効になっていないコードを呼び出しも、問題は発生しません。これは、外部C関数またはその性質のものを呼び出すことと同じです。

例外が有効になっていないコードから(例外が有効なコードに)呼び出すと、例外が無効になっているコードに正しいスタック巻き戻しセマンティクスが含まれない可能性があります。つまり、特別に設計されていない限り、そのコードの不変条件を壊すことになります。例外。(たとえば、一部のライブラリ(ANTLRなど)は、ブロック内のすべてのメモリを割り当て、ユーザーコードですべてを一度に解放します。これにより、ライブラリ自体が例外を使用しなくても、リークすることなく例外を使用できます)。

Raymond Chenは、C++の例外処理がMSVC++でどのように機能するかについての内部記事をかなり掲載しています。簡単に言うと、WindowsのSEHの上に構築されています。したがって、CコードなどでSEH例外をスローした場合と同じように動作するはずです。(ただし、これは自分で確認していません)

于 2011-06-29T19:35:29.680 に答える
5

MSDNによると、/EHaと/EHscを混在させることができます。

同期と非同期の2つの例外処理モデルは完全に互換性があり、同じアプリケーションに混在させることができます。

ただし、このルールには例外があるようです。これは、アンマネージ(/ EHsc)からマネージ(/ clr)に例外を渡す場合です。マネージドコードは、構造化例外処理(SEH)を使用してすべての例外をキャッチします。これにより、スタックをアンワインドするときにアンマネージドデストラクタが呼び出されなくなります。さまざまな回避策があります。

  1. アンマネージコードを変更して、/EHscの代わりに/EHaを使用します。これには、アンマネージコード内のcatch(...)が突然アクセス違反やその他のクレイジーなものをキャッチするという欠点があります。
  2. アンマネージコード内にtry-catchブロックを作成し、アンマネージワールドとマネージドワールドの間で例外が渡されないようにします。

    2.1。考えられる中間の道は、アンマネージドワールドからマネージドワールドに例外を渡すときにデストラクタが呼び出されないようにすることです。アンマネージコード内でtry-catchラッパーを作成し、catchブロック内で例外をマネージドワールドに再スローします。

于 2011-12-10T00:01:25.173 に答える