当面の問題は解決されましたが、クラスの vtable を構築するためにどのデータが使用され、vtable のレイアウトがどこに保存されるかについて、少し混乱しています。誰かが説明を提供してくれたり、私の好奇心を満たしてくれる情報を教えてくれたりできれば、とてもありがたいです。
バックグラウンド
- 2 つの個別の VC6.0 プロジェクト: 1 つは exe 用、もう 1 つは dll 用です。
- アプリケーションには、dll プロジェクト リリースの .lib、.dll、および .h ファイルが含まれています。
- 新しいリリースの準備が整うと、.lib、.dll、および .h ファイルがdll プロジェクトから exe プロジェクトにコピーされます。
- この仕組みを受け継いでいます。
問題:
最近、DLL に変更を加え、.lib と .dll をコピーしましたが、ヘッダー ファイルをコピーするのを忘れていました。いくつかの階層の変更があり、その結果、1 つの特定のクラス ( と呼びますInternalClass
) の vtable が変更されました。
exe は のメソッドを直接呼び出しませんInternalClass
。代わりに、オブジェクトInterfaceClass
へのポインターをカプセル化し、そのポインターに対してさまざまなメソッドを呼び出す別のクラスのインスタンスを作成します (それを呼び出します) 。InternalClass
実行時に、メソッド内からInterfaceClass
メソッドへInternalClass
の呼び出しが、実際には間違ったメソッドを呼び出していました(つまり、InterfaceClass
呼び出しInternalClass::A
てInternalClass::B
実際に実行されていました)。asmを見ると、フィックスアップまたはサンク (専門用語が間違っていたらすみません!) がvtable への正しいオフセットを使用していたことがわかります。ただし、vtable 自体には、古いヘッダー ファイルから期待されるポインタのリストが含まれていました。
実際の質問:
私は自分の間違いに気づき、ヘッダー ファイルをコピーして再コンパイルしましたが、すべて問題ありませんでした。ただし、1 つのしつこい質問が残っています。
vtables のレイアウトはいつ決定され、実行時にこれらのクラスの vtable を構築するためにどのような情報が使用されますか? つまり、dll がコンパイルされたときに適切なvtable がアセンブルされている必要があり、オフセットなどを からInterfaceClass
への呼び出しに使用できるように思われInternalClass
ます。では、なぜ実行時に古い vtable が使用されたのでしょうか? exeが持っているヘッダーを使用してコンパイルされたときに、レイアウトも個別に決定されますか?
これがまったく明確かどうかはわかりません。私が求めていることが複雑すぎる場合はお知らせください。ありがとう!