0

次のようなコードのC++DLLがあります。

LogMessage( "Hello world" );
try {
    throw new int;
} catch( int* e ) {
    LogMessage( "Caught exception" );
    delete e;
}
LogMessage( "Done" );

このDLLはサードパーティのアプリケーションによってロードされ、上記のコードが呼び出されます。問題は、最初LogMessageに呼び出されるだけです。例外ハンドラーがある場合でも、制御フローは不明に転送されます。

私はこれを見て、それが調査すべきいくつかのあいまいなバグなのか、それとも単にコンシューマーアプリケーションの邪悪な力なのかを判断できません。

コンシューマーアプリケーションがDLLのC++例外処理をオーバーライドすることは本当に可能ですか?

編集:答えに概説されているチェックするすべてのことを考えた後、問題は解決しました。実際のコードでは、スローするだけでなく、デバッグバージョンでMessageBoxW()Win32呼び出しを呼び出す例外をスローするための特別な関数があります。また、コンシューマーアプリケーションはメッセージボックス(NTサービス)を表示するのに問題があり、効果的に電話を切りました。したがって、C++例外処理の問題ではありません。

4

5 に答える 5

1

コードはOKです。私はこの関数でそれを実行しました:

void LogMessage( char* s )
{
  cout << s << endl;
}

そして正しい出力を得ました:

こんにちは世界

キャッチされた例外

終わり

LogMessage関数に問題がある可能性はありますか?

フローがtryブロックに到達するかどうか、およびフローがcatchブロックに到達するかどうかを、(デバッガーまたはデバッグ印刷の追加によって)調査することをお勧めします。

問題ではありませんが、それでも明確ではありません。値ではなくポインタをスローすることで何を達成できますか。C++-FAQ-liteのcatch-by-pointerを使用しないことをお勧めします。ここの理由を参照してください。

于 2009-05-27T07:18:58.350 に答える
1

コードは私には問題ないように見えますが、いくつかの catch 句を追加して、他の句の 1 つにヒットしているかどうかを確認したくなるでしょう。つまり、次のように入力します。

  catch (const std::exception &ex) {
    ... log exception ...
  }
  catch (...) {
    ... log exception ..
  }

ポインター キャッチ (それが本当に良い考えでなくても、Igor Oks が提供したリンクを参照してください) または std::exception (メモリを割り当てられない場合) にヒットすることを期待します。つまり、3 つの catch 句のいずれかにヒットする必要があるため、例外が DLL をエスケープする方法はありません。

また、スローされるオブジェクトを値型に変更し (int であっても)、それに応じて catch 句を更新して、そのように動作が変更されるかどうかを確認します。

于 2009-05-27T07:30:03.667 に答える
1

最初に、LogMessage呼び出しが出力をフラッシュするかどうかを確認してください ( を使用<< endl)。

大げさではありますが、新しい呼び出しが例外をスローしている (メモリ不足) 可能性はありますか? 私はそれを新しい例外にしない理由の1つと考えています(Igorが言ったことに追加するだけです)。

于 2009-05-27T07:44:48.553 に答える
1

コードは問題ないようです。throw new int;しかし、構造化例外がスローされる前に未処理の例外があるかどうかを確認できますか。

LogMessage( "Hello world" );
try {

     //some unhandled exception here 

    throw new int;
} catch( int* e ) {
    LogMessage( "Caught exception" );
    delete e;
}
LogMessage( "Done" );

その場合は、SetUnhandledExceptionFilter関数を使用して同じことを確認できます。

DLL が未処理の例外フィルターを既に提供しており、それが返されEXCEPTION_EXECUTE_HANDLERた場合、例外ハンドラーは呼び出されません。

_set_se_translatorwin32 例外を C++ 構造化例外に変換するために使用する必要があります。

于 2009-05-27T07:47:24.337 に答える
0

景品は実際にはEDITにあります。"MessageBoxW() ... NT サービス ... 事実上ハングアップしました。". それは公正な説明です。メッセージ ボックスは、ログインしているユーザーに関連付けられていないデスクトップにあります。したがって、決して起こらないマウスクリックを待って、まだそこにあります。

于 2009-05-28T11:24:02.450 に答える