Hello all,
Although the problem at hand is solved, it has me a little confused as to what data is used to construct the vtables for a class and where the layout for the vtable is stored. If anyone can provide clarification or point me towards some information which might satiate my curiosity, I would greatly appreciate it.
Background
- Two separate VC6.0 projects: one for an exe, one for a dll.
- Application contains .lib, .dll and .h files from dll project releases.
- When a new release is ready, the .lib, .dll, and .h files are copied into the exe project from the dll project.
- I have inherited this scheme.
Problem:
I recently made a changes to the DLL and copied over the .lib and .dll but forgot to copy the header files. There had been some hierarchy changes and, as a result, the vtable for one particular class (call it InternalClass
) had changed.
The exe does not directly invoke any methods on InternalClass
. Instead, it creates an instance of a different class (call it InterfaceClass
) which encapsulates a pointer to an InternalClass
object and invokes various methods against that pointer.
At runtime, calls made from within InterfaceClass
methods to InternalClass
methods were actually invoking the wrong methods (i.e. InterfaceClass
would invoke InternalClass::A
and InternalClass::B
would actually run). Looking at the asm, it turns out that the fixup or thunk (I'm sorry if this is the wrong jargon!) was using the correct offset into the vtable. However, the vtable itself contained the list of pointers you would expect from the old header files.
Actual Question:
I realized my mistake, copied the header files over, recompiled and all was well. However, I am left with one nagging question:
When is the layout for the vtables determined and what information is used to construct the vtable for these classes at runtime? That is, it seems to me that the proper vtable must have been assembled when the dll was compiled so that the offsets, etc could be used for the calls from InterfaceClass
to InternalClass
. Why, then, was an outdated vtable used at runtime? Is the layout also determined separately when the exe is compiled using the headers it has?
I'm not sure if this is at all clear. Let me know if what I'm asking is too convoluted. Thanks!