Хотя проблема под рукой решена , меня немного смущает вопрос о том, какие данные используются для создания виртуальных таблиц для класса и где хранится макет виртуальной таблицы.Если кто-то может дать разъяснения или указать мне какую-то информацию, которая могла бы удовлетворить мое любопытство, я был бы очень признателен.
Фон
- Два отдельных VC6.0проекты: один для exe, один для dll.
- Приложение содержит файлы .lib, .dll и .h из выпусков проекта dll.
- Когда новый выпуск готов, .libФайлы .dll и .h копируются в проект exe из проекта dll.
- Я унаследовал эту схему.
Проблема:
Недавно я внес изменения в DLL и скопировал файлы .lib и .dll, но забыл скопировать файлы заголовков .Произошли некоторые изменения в иерархии, и, как следствие, изменилась vtable для одного конкретного класса (назовите его InternalClass
).
exe не напрямую не вызывает никаких методов на InternalClass
.Вместо этого он создает экземпляр другого класса (назовите его InterfaceClass
), который инкапсулирует указатель на объект InternalClass
и вызывает различные методы для этого указателя.
Во время выполнения вызовы выполняются из InterfaceClass
методы к InternalClass
методы фактически вызывали неправильные методы (то есть InterfaceClass
будет вызывать InternalClass::A
и InternalClass::B
будет фактически выполняться).Глядя на asm , выясняется, что исправление или thunk (извините, если это неправильный жаргон!) Использовал правильное смещение в vtable. Однако , сама таблица содержит список указателей, которые можно ожидать от старых заголовочных файлов.
Актуальный вопрос:
Я осознал свою ошибку, скопировал заголовочные файлы, перекомпилировал и все было хорошо. Однако , у меня остался один мучительный вопрос:
Когда определяется макет для vtables и какая информация используется для создания vtable для этих классов во время выполнения?То есть мне кажется, что правильная vtable должна была быть собрана при компиляции dll, чтобы смещения и т. Д. Могли использоваться для вызовов от InterfaceClass
до InternalClass
.Почему тогда во время выполнения использовался устаревший vtable?Разметку также определяют отдельно, когда exe-файл компилируется с использованием заголовков?
Я не уверен, что это вообще понятно. Дайте мне знатьесли то, что я спрашиваю, слишком запутанно.Спасибо!