以下を実行するコードを実行時に生成する必要があります。
auto v_cleanup = std::shared_ptr<void>(nullptr, [](void *){ cleanup(); });
//...
do_some_danger_thing();
//...
または同等の C:
__try {
//...
do_some_danger_thing();
//...
} __finally {
cleanup();
}
cleanup() 関数は例外がないことが保証されていますが、 do_some_danger_thing() は例外をスローする場合があります。このランタイム コードはスタックを使用してはなりません。つまり、do_some_danger_thing() を呼び出すとき、ランタイム コードに設定された戻りアドレスを除いて、スタックはランタイム コードに入るときと同じ状態でなければなりません (元の値は "jmp に保存されました)。 " ターゲット、呼び出し元に戻るため)。
動的マシン コードを使用しているため、ターゲット プラットフォームは x86 CPU 上の WIN32 に固定されており、x64 CPU は現在注目されていません。
これを行うには、例外を処理する必要があります。WIN32 では、C++ 例外は SEH ベースであるため、それに対応する必要があります。問題は、これを行う方法を見つけられず、他のコードと互換性がないことです。いくつかの解決策を試しましたが、どれも機能しません。ユーザーがインストールした例外ハンドラーが呼び出されなかったり、外部の例外ハンドラーがバイパスされたりして、「ハンドルされていない例外」エラーが発生することもありました。
アップデート:
SEH 例外ハンドラ チェーンが EXE イメージ内のコードのみをサポートしているようです。例外ハンドラーが生成されたコードを指している場合、それは決して呼び出されません。私がしなければならないことは、静的例外ハンドラー関数スタブを作成し、生成されたハンドラーを呼び出させることです。