Search code examples
c++memorystructshared-libraries

Cross Compiler Library Interaction (Dynamic Loading) (plugins)


This is so much a problem as verification of my reasoning.

Anyway I'm working on a complex project that will support plugins (libraries loaded dynamically at run time), Now I would like to be able to have the main program compiled with compiler X and the plugin compiled with compiler Y, and the plugin still work. However I will need to pass complex data between the plugin and the main programs.

So my understanding is that standard functions are fine doesn't matter the compiler as long as I known the address they will execute the same basic code.

However when it comes to structs, 2 identical structs may not be the same due to alignment/packing method differing between compilers, however I can override this using #parama pack(n) on most compilers, and as long as this is the same the memory structure of these structs will match so they can be passed between the plugin and the main program.

Now then I believe this will also hold true for basic classes as long as there are no virtual functions, and all member variables are public.

However I can't relie on the calling conventions of member functions, so I must either map them though a standard function that takes the object as a parameter, or reimplemented them in the plugins namespace, most likely through a library its linked against.

Further more I should be able to implement operators and member functions for the structs/classes as long as they are implemented as above.

Hence I can use this for passing complex data between plugin and program, even though they were compiled with different compilers.

I'm I correct in my understanding here?


Solution

  • Yes, you seem to have most of the important points there. Essentially the DLLs must only expose a C-level interface, rather than many of the nifty features that C++ provides. (Although it's still possible to use C++ internally of course.)

    One important point you didn't mention is that any memory allocated by a plugin must be deallocated by that same plugin. And similarly the main program must be the one to deallocated anything that it allocated. You can pass the memory addresses back and forth and use them fine, but deallocation is a special case because different compilers may use differing implementations of their heaps. Thus bad things could happen if one tries to clean up memory that it wasn't responsible for in the first place.