Objects across DLL boundary

Started by
12 comments, last by NotAYakk 15 years, 9 months ago
"Just so I'm clear, what do you mean by this exactly?"

This will allow primitive data types with no 'issues'. I get the impression you already know this, and it doesn't answer your question, but I believe this is what he means...


#ifdef API_EXPORTS#define API extern "C" __declspec(dllexport)#else#define API extern "C" __declspec(dllimport)#endifAPI void my_c_linkage_func() {}


As to your OP, getting C++ objects across stuff from two different compilers is voodoo. If you insist on doing it, keep it simple and use lots of pragmas to explicitly define everything.
Advertisement
Re-reading some of the replies makes me feel that perhaps I haven't been clear, and that I don't fully understand the problem I face.

Quote:fread, where you pass the instance of the object (file handle) to the function on which it is going to preform.

I read this (and the other similar replies) to mean that as long as I keep the allocation/deallocation on one side I'm fine? Or is this just not the case?

This
Quote:As to your OP, getting C++ objects across stuff from two different compilers is voodoo.

Would confirm the latter.

Thanks!
It's more than keeping allocation/deallocation on one side: it's also about accessing the members of your object from the same side which allocates it since that's the only side which is guaranteed to know how to access the members properly. You give the consumer some C functions which act as wrappers to using member functions of the object itself.
Something like this is an option:
struct Plugin_Data; // to be defined by client, never used on the servertypedef void (func1_with_better_name_than_this)(Plugin_Data*, int, int, bool);typedef bool (func2_etc)(Plugin_Data*, double, double);struct Plugin_Struct {  size_t length; // for backward/forward compatibility  Version v; // for backward compatibility  Plugin_Data* data;  func1_with_better_name_than_this* f1_should_have_better_name;  func2_etc* f2_also_should_have_better_name;};// NEVER passed between DLLs:class PluginInstance {  private:    Plugin_Struct data;    PluginInstance(); // not implemented  public:    PluginInstance(PluginData* data_):data(data_){};    PluginData* raw() {      return data;    };    static PluginInstance from_raw(PluginData* raw) {      return PluginInstance(raw);    };    void f1_should_have_better_name(int a, int b, bool c) {      data->f1_should_have_better_name(a, b, c);    };    // etc};


The idea is you have a pure-C interface, a struct that provides a list of "methods" on an abstract data class, and a C++ class that wraps it and makes it look like nice OOP.

If you can manage to specify the packing of your Plugin_Struct, and only allow it to be passed over DLL bounderies, you get polymorphic behavior from your PluginInstance class.

Of course, this does end up being a lot of headache, for both you and your client. :)

You can make it easier by writing code that takes an abstract interface, and then turns it into a Plugin_Struct. This would let clients use OOP, turn the result into a Plugin_Struct, and then let you use OOP on your side as well.

This topic is closed to new replies.

Advertisement