Thank you for the interest and suggestions, but DLL linking is not the issue. The problem is that we're dealing with three types of vtables (the ones in the game, the ones in the DLL produced by MSVC, the ones in the DLL produced by GCC) and they all have to match perfectly. The first two match just fine given correct declarations since they're produced by the same compiler, but the GCC version does a lot of things differently.
The requirement for perfect match comes from the way vtables work in C++ - at compilation time, a table of pointers to virtual functions of that class is composed and a pointer to said table is included in each object of that class. When you call a virtual function on an object of that class or its derivates, the compiler uses its index (X) in this table and the generated assembly code instructs the cpu to access the vtable through the object's pointer and call the X'th function in it.
Now, when we extract a pointer to an instance of, say, InfantryClass, from the game, the vtable pointer points to the vtable the compiler composed and weaved into the game at compilation time. When we actually create an instance of InfantryClass in the DLL, the initial vtable pointer points to a table that was generated at DLL compilation time, but is immediately overwritten with the one from the game. But in both cases, the actual calls to the object's virtual functions we write in the DLL source are transformed to the offset calls by the DLL compiler who follows only its own vtable layout.
For things to work correctly, both the game and the DLL vtables have to point to the same functions in the same order. Unfortunately, MSVC uses one class composition model, GCC uses another one, documented at
http://www.codesourcery.com/public/cxx-abi/abi.html and deceivingly titled "for Itanium". The two models are incompatible and classes will have largely different vtables. The longer the inheritance chain grows, the more different they will be. In my experience, GCC also adds/removes some additional data to the object itself, shifting the offsets of member variables too. I'm not certain whose composition model is better, gcc's or msvc's, but since the game dictates the rules, we have to go with msvc.
If you want a testcase, you can checkout the actual YRPP source from svn://renegadeprojects.com/yrpp/trunk and tell gcc to compile YRPP.h with -fdump-class-hierarchy , open the .class file it produces, search for "vtable for InfantryClass" and compare the list of function names with the list of virtual functions that were actually declared.
Administrative Notice:
Splitting off to a separate geeky thread.