Arkady
Arkady

Reputation: 2207

Loading classes from DLL that was exported by another compiler

I have to explain my team why exporting classes from DLL is not good solution, if we plan to use that DLL from different compiler. But I can't find prove for that. Is there something in standart like "compiler shouldn't supply backward compatibility, also different compilers can implement their own style of naming exporting symbols, so exported class from DLL can be used then just by same compiler"? I know it is true, but how can I prove that? Also, if you know additional arguments for me, please, help!

Upvotes: 0

Views: 395

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283793

Different compilers use different runtime libraries. std::string, std::vector<int>, std::shared_ptr all have different implementations. Classes have different layout (alignment and packing are only part of layout). Assumptions about this layout get baked into both modules if there is even a single inline function, anywhere, as well as at object creation when memory needs to be allocated.

There's a reason that C++ has the One Definition Rule, and as soon as you start mixing compilers, or even different compiler options, that rule is violated.

These are the things that can safely be shared:

  • Standard-layout data-only classes, as long as you are careful to match deallocator to allocator. You can't free across library boundaries. Also packing needs to be set identically on both sides.
  • Pure virtual base classes, which contain only pure virtual instance member functions. No instance data, and no static anything. No inheritance between interfaces. And only the module with the concrete subclass where the interface(s) are implemented is allowed to cast between interface pointers.

Note that neither of these require dllexport. Just including the same header file with the same packing options is enough, because functions are found through the v-table, not through DLL imports.

Of course you'll also want C-compatible global function exported from the DLL, to bootstrap creation of the objects. For those __declspec(dllexport) will be used, or a module definition file. Also I recommend extern "C" for these global exports.

I strongly recommend that you read about the "Component Object Model" (COM), which goes under various other names such as DCOM, ActiveX, etc. You don't need to use all of the same mechanics, which get quite complicated, but try to understand at a minimum how the "interfaces with virtual functions only" and "reference counting with self-deallocation" along with "inheritance graph is traversed by the object itself" schemes provide the ability to mix different languages and compilers. (Side note: the existence of COM is the reason that v-table-only classes are compatible, because COM is a Windows standard for v-table layout. It's as close as Windows gets to an ABI.)

Upvotes: 2

djikay
djikay

Reputation: 10648

Here are a few points that you may find interesting/useful to tell your team.

  • Different compilers mangle C++ names differently. This simple name mangling issue may be possible to circumvent with an explicit .def file.

  • Different structure alignment issues which need the correct compiler options (-mms-bitfields, ...).

  • A fundamental conflict of underlying exception and memory models:

    • A new/delete or malloc/free in a MSVC DLL will not co-operate with a Cygwin newlib new/delete or malloc/free. One cannot free space which was allocated in a function using a different new/malloc at all.

    • An exception raised by an MSVC DLL will not be caught by a Cygwin executable, and vice versa.

    • The slow GNU SJLJ exception model, (used in GCC-3.x and earlier), is compatible with the MSVC++ model, but the new DWARF2 model, (which will be used by GCC-4.x), will be incompatible.

A more complete explanation is given here, from where I shamelessly copied the above. Seeing as you use MinGW, this should be very relevant.

Also, if you haven't done so already, take a look at the discussion for this SO question.

Upvotes: 3

Vert
Vert

Reputation: 29

Um.. I thought only extended dll can loading c++ classes and extended dll is for MFC, so only visual studio can make I gues...

Upvotes: 0

Related Questions