1

私は現在、閉じた作業中のプロジェクトの拡張機能であるDLLに取り組んでいます。

純粋な呼び出しのバグをすべてキャッチしたいので、グーグルで検索して_purecallハンドラーについて調べました。私の質問はそれの実装についてです。舞台裏で何が起こっているのですか?コンパイラ自体がハンドラー関数アドレス(定義した場合)を取得し、クラス関数アドレス自体(初期化後)によってオーバーライドされる前に、vテーブルの各行にデフォルト値を書き込みます。 CRTとグローバルポインタ?

もちろん、プラグインDLLがアプリケーションの_purecallハンドラー全体を上書きしたくないので、これを求めています。purecallハンドラーがモジュール内のpurecallのみを処理することを確認できますか?

ありがとう!

4

1 に答える 1

1

答えは、コンパイラが purecall ハンドラを実装する方法に大きく依存します。コンパイラが仮想関数テーブル内の「純粋な」関数ポインタを単純に置き換える場合、親プロセスの動作を変更しても問題ありません。

ただし、一部のコンパイラは、CRT のハンドラーからハンドラーを呼び出すことにより、カスタムの purecall ハンドラーを実装します。この場合、動作は DLL のビルド方法によって異なります。CRT に静的にリンクした場合、DLL はすべての CRT 状態の独自のインスタンスを持ちます。この場合、コンパイラの実装は関係ありません。purecall ハンドラーが親プロセスに干渉することはありません。

一方、CRT に動的にリンクした場合、動作はホスト プロセスがどのように構築されたかによって異なります。DLL と同じバージョンの CRT に動的にリンクされている場合、purecall ハンドラーが実際に干渉する可能性があります。ただし、これもコンパイラの実装に依存します。CRT からフックを呼び出している場合でも、CRT がモジュールごとに異なるフックを保持していれば安全です

いずれにせよ、確実に安全を確保したい場合は、DLL を CRT に静的にリンクするか、purecall ハンドラーの使用を避ける必要があります (代わりに、抽象クラスの代わりに具体的な基本クラスを使用することもできます)。

于 2011-03-18T19:19:37.787 に答える