Вы должны иметь возможность смешивать модули, построенные с разными компиляторами, если вы снизите свои ожидания и будете придерживаться простых функций.
То, как ведут себя классы и виртуальные функции, определяется стандартом C ++, но способ, которым это реализуется, зависит от компилятора. В этом случае я знаю, что VC ++ создает объекты, которые имеют виртуальные функции с указателем «vtable» в первых 4 байтах объекта (я предполагаю, 32-битный), и это указывает на таблицу указателей на запись метода точек.
Итак, строка: dllclass->PrintSomething();
на самом деле эквивалентно что-то вроде:
struct IClassVTable {
void (*pfIClassDTOR) (Class IClass * this)
void (*pfIRefCountedAddRef) (Class IRefCounted * this);
void (*pfIRefCountedRelease) (Class IRefCounted * this);
void (*pfIClassPrintSomething) (Class IClass * this);
...
};
struct IClass {
IClassVTable * pVTab;
};
(((struct IClass *) dllclass)->pVTab->pfIClassPrintSomething) (dllclass);
Если компилятор g ++ реализует таблицы виртуальных функций каким-либо образом, отличным от MSFT VC ++ - так как он бесплатен и по-прежнему соответствует стандарту C ++ - это будет просто сбой, как вы продемонстрировали. Код VC ++ ожидает, что указатели функций будут в определенных местах в памяти (относительно указателя объекта).
Это усложняется наследованием и действительно, действительно, усложняется множественным наследованием и виртуальным наследованием.
Microsoft очень открыто рассказывает о том, как VC ++ реализует классы, поэтому вы можете писать код, который зависит от него. Например, у многих заголовков COM-объектов, распространяемых MSFT, есть привязки C и C ++ в заголовке. Привязки C раскрывают свою структуру vtable, как это делает мой код выше.
С другой стороны, GNU - IIRC - оставил открытой возможность использования разных реализаций в разных выпусках, и только гарантия того, что программы, созданные с его компилятором (только!), Будет соответствовать стандартному поведению,
Короткий ответ - придерживаться простых функций в стиле C, структур POD (Plain Old Data; т.е. без виртуальных функций) и указателей на непрозрачные объекты.