2009-07-07 1 views
1

Ужасный заголовок Я знаю и ужасный вопрос. Я работаю с небольшим количеством программного обеспечения, где dll возвращает ptr во внутренний класс. Другие библиотеки (вызов DLL), а затем использовать этот указатель для вызова методов этого класса непосредственно:C++ Изменение класса в dll, где указатель на этот класс возвращается в другие dll

//dll 1 
internalclass m_class; 
internalclass* getInternalObject() { 
    return &m_class; 
} 

//dll 2 
internalclass* classptr = getInternalObject(); 
classptr->method(); 

Это пахнет очень плохо для меня, но это то, что у меня есть ... Я хочу, чтобы добавить новый метод internalclass поскольку одна из вызывающих библиотек требует дополнительных функций. Я уверен, что все DLL, которые обращаются к этому классу, нужно будет перестроить после включения нового метода, но я не могу разобраться в логике причины.

Я думаю, что это как-то связано с уже скомпилированной вызывающей DLL, имеющей физический адрес каждой функции внутри внутреннего класса в другой DLL, но я на самом деле не понимаю этого; кто-нибудь здесь может предоставить краткое объяснение того, как dll (новая внутренняя библиотека dll, перестроенная вызывающая DLL и вызывающая dll, построенная с предыдущей версией dll внутреннего класса) будут соответствовать друг другу?

Спасибо, Патрик

ответ

2

Клиент DLL файлы «узнать» фактический адрес класса функций на время загрузки путем поиска на таблице экспорта обслуживающей DLL. Поэтому, пока таблица экспорта остается совместимой, никакого вреда не делается.

Совместимость будет нарушена, если ваш класс имеет таблицу виртуальных функций, а функции в нем меняют порядок. Он также сломается при связывании по порядку, а не по символу.

+0

Итак, если метод не виртуальный, это будет нормально (даже если другие методы в классе (деструктор) являются виртуальными?) – Patrick

+0

Пока вы связываете по имени, а не по порядку – xtofl

+0

Я предполагаю, что порядок функций в таблице vtable Решили по порядку они находятся в определении класса? – Patrick

2

Вы должны возвратили PTR на производный объект класса в качестве типа базового класса. Затем вы можете свободно изменять производный класс. Однако не могу изменить базовый класс.

Редактировать: вы можете изменить его. Но осторожно. Добавление методов должно работать (если только они не являются виртуальными). Добавление переменных может работать, если вы добавите их в конце.

2

Нет, перестройка, скорее всего, не понадобится.

За кулисами внутренний класс :: метод() будет искажен чем-то вроде internalclass__method(internalclass* __this). Эта измененная функция затем экспортируется по имени из вашей DLL.

+0

Это будет необходимо, только если будут играть таблицы виртуальных функций. – xtofl

+0

Кроме того, если метод() является виртуальным. Но в этом случае вы будете в порядке, пока вы добавите новую функцию в конец vtable. – Ralph

+0

Я, возможно, слишком подсознательно читал «использовать этот указатель для вызова методов этого класса * напрямую» и «уже скомпилированный вызывающий DLL, имеющий физический адрес каждой функции». – MSalters

0

Не трогайте существующий класс и возвращает указатель на производный класс в новой функции getInternalObject_ex()

Смежные вопросы