尽管手头的问题已经解决,但对于使用什么数据来构造类的 vtable 以及 vtable 的布局存储在哪里,我还是有点困惑。如果有人可以提供澄清或指出一些可能满足我好奇心的信息,我将不胜感激。
背景
- 两个独立的 VC6.0 项目:一个用于 exe,一个用于 dll。
- 应用程序包含来自 dll 项目版本的 .lib、.dll 和 .h 文件。
- 当新版本准备就绪时,.lib、.dll 和 .h 文件将从 dll 项目复制到 exe 项目中。
- 我继承了这个方案。
问题:
我最近对 DLL 进行了更改并复制了 .lib 和 .dll 但忘记复制头文件。层次结构发生了一些变化,因此,一个特定类(称为它InternalClass
)的 vtable 发生了变化。
exe 不会直接调用InternalClass
. 相反,它创建了一个不同类的实例(称为它InterfaceClass
),它封装了一个指向InternalClass
对象的指针并针对该指针调用各种方法。
在运行时,从InterfaceClass
方法内部对InternalClass
方法的调用实际上是在调用错误的方法(即InterfaceClass
会调用InternalClass::A
并InternalClass::B
实际运行)。查看asm,事实证明 fixup 或 thunk(如果这是错误的行话,我很抱歉!)正在使用正确的偏移量到 vtable 中。但是,vtable 本身包含您希望从旧头文件中获得的指针列表。
实际问题:
我意识到我的错误,将头文件复制过来,重新编译,一切都很好。然而,我留下了一个挥之不去的问题:
何时确定 vtable 的布局以及在运行时使用哪些信息为这些类构建 vtable?也就是说,在我看来,在编译 dll 时必须已经组装了正确的vtable,以便偏移量等可以用于从InterfaceClass
to的调用InternalClass
。那么,为什么在运行时使用过时的 vtable 呢?使用它拥有的头文件编译exe时,布局是否也单独确定?
我不确定这是否完全清楚。让我知道我的要求是否过于复杂。谢谢!