5

I'm planning on doing a C++ plugin interface ala How to create some class from dll(constructor in dll)?(с++) but concerns have been raised that if the interface is used to create DLLs via MinGW or Borland and the DLL loader is compiled with MSVC++, there might be problems. Since the only exported function is declared extern "C" I fail to see why it would not work ?

Ideas ?

Community
  • 1
  • 1
Robert
  • 2,330
  • 29
  • 47

2 Answers2

11

If you want to be compatible across compilers (and Release / Debug) and use C++, you need a little more effort.

Basically - you are allowed to pass basic datatypes, and pointer to pure virtual classes. These classes must not contain any data member, their destructor must not be public and they should not have overloaded functions.

Memory must not be allocated in one dll and released in another. This means no exceptions and you need some kind of reference counting or returning mechanism.

All methods inside pure virtual class (aka "Interface") must be marked with a call convention (I'd prefer stdcall).

Dynamic casts are not possible as well, so you might need some functionality in all your interfaces to do the trick (like QueryInterface in COM).

This works because most compiler on win32 try to be COM compatible and solve the same problems in a COM compatible way. For getting the first interface, you need a plain C function that is exported from the dll.

If you just use C functions and C data types, everything will work as well. But then you are limited to C without classes & inheritance.

I hope that helps.


Name mangling is not a problem:

1st: if you use C functions with C data types, everything is defined, there's no name mangling (exception: in VS with STDCALL, you need to remap the name to the "normal" C name via Linker directive)

2nd: Methods inside classes are not exported and thus not mangled. You call methods via pointer to pure virtual classes (aka "Interfaces"). This uses an offset and no name. You still can't use the destructor, as the position of the destructor inside the vtbl is not fixed as far as I know.


If you pass structs to functions / methods, be sure to fix the alignment. It is not defined across different compilers.

Tobias Langner
  • 10,634
  • 6
  • 46
  • 76
  • What about name mangling? Will it be the same for the destructor in different compilers? – ssmir Jan 21 '11 at 09:18
  • So that means that you can't use a plugin made with a different compiler because the symbol for the vtable can be different and even method offsets can be different? – ssmir Jan 21 '11 at 11:31
  • But isn't the vtable structure defined by C++ standard ? Then it should be no problem to use a different (compliant) compiler. – Robert Jan 21 '11 at 13:08
  • @Robert It's not defined by the standard http://en.wikipedia.org/wiki/Virtual_method_table – ssmir Jan 21 '11 at 13:37
  • you can use plug-ins made with different compilers as long as the compiler vendors obey some kind of rules. This was done on windows by MS defining COM. Everything that is available in COM that maps directly to C++ can be used across most compilers. What does not map are (to my experience) non C-type arguments (e.g. std::string), destructors & overloaded functions. – Tobias Langner Jan 21 '11 at 14:57
  • @Tobias My interface structure is really simple with only POD (C) types, so I guess it'll work fine :) – Robert Jan 21 '11 at 15:20
  • 1
    @Robert @Tobias Thanks, that's interesting. I mean the fact that compilers on Windows use the same virtual table layout. Another answer which helped me to understand: http://stackoverflow.com/questions/2032939/why-com-component-object-model-is-language-independent/2032969#2032969 – ssmir Jan 21 '11 at 16:20
  • @ssmir Thanks for that cross reference. – Robert Jan 23 '11 at 13:22
0

An idea could be using standard extern C function to create a ClassFactory. Have some convenction about a fixed ( or more ) entry point the dll must expose to be a valid plugin.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
  • Yes, the only function exported would be an extern "C" Plugin* GetPluginObject(). I've done this before, but then I had control of the DLLs (i.e. not letting MinGW/Borland etc. into the equation) – Robert Jan 21 '11 at 09:04
  • What about if your GetPluginObject returns an istance of some class derived from some *pure* virtual class, aren't the VTable compatible between different compiler implementation ? I think MS COM leverages these ideas... – Felice Pollano Jan 21 '11 at 09:06
  • they are, to some extend. See my answer above. – Tobias Langner Jan 21 '11 at 14:58