Exporting a class to DLL for gnu from msvc
How would the def file look for exporting a class, or if not using a def file, where would you put declspec(dllexport) and/or extern "C".
I searched google for answers but to no avail.
If you want to export a class from a DLL using VC++ then you would write the __declspec(dllexport) like so:
I've never seen the extern "C" construct used with exporting classes so I'm not sure if it even has any effect. The primary method I've seen it used is with exporting functions from a C++ DLL. Specifying the extern "C" tells the compiler to use C style linkage for those functions so you can call them from the client application by using their original name. You only need this for C++ dlls because of the name mangling which occurs.
class __declspec(dllexport) CTest{ //blah};
I've never seen the extern "C" construct used with exporting classes so I'm not sure if it even has any effect. The primary method I've seen it used is with exporting functions from a C++ DLL. Specifying the extern "C" tells the compiler to use C style linkage for those functions so you can call them from the client application by using their original name. You only need this for C++ dlls because of the name mangling which occurs.
C++ classes are incompatible between compilers. It can't be done.
...Unless you're willing to do some serious assembly code mucking, but it's likely not worth it.
...Unless you're willing to do some serious assembly code mucking, but it's likely not worth it.
What you can do though is export 2 functions that create and destroy an instance of an interface to your class. This works because the virtual function table provides the pointers to all of the relevant code, there's no need for the class's member functions to be exported from the DLL. It goes a little something like this.....
In a common header shared by both the DLL and executable (or another DLL):
In your DLL:
In a common header shared by both the DLL and executable (or another DLL):
class IMyClass{public: // Important, this ensure the correct destructor // is called when a derived class is destroyed. virtual ~IMyClass() =0; // The interface to your class virtual void DoSomething() = 0;};
In your DLL:
class MyClass : public IMyClass{public: // The virtual keywords aren't strictly necessary, // but I usually put them in to make it clear they're // implementing functions from the base class virtual ~MyClass() { ... } virtual void DoSomething() { ... }};// I've used a raw pointer here, using smart pointers// would be better (but watch out for problems with// the DLL using a different heap, which it probably// will if you're using 2 different compilers)declspec(dllexport) IMyClass* CreateMyClass(){ return new MyClass();}// Objects should be deleted from inside the DLL since the// calling executable could be using a different heap, hence// the existence of this functiondeclspec(dllexport) void DestroyMyClass(IMyClass* obj){ delete obj;}
To follow on this particular subject :
How can one be sure the virtual functions in the v-table are ordered the same by different compilers ?
How can one be sure the virtual functions in the v-table are ordered the same by different compilers ?
Quote:Original post by cnstrndYou can't, but in practice, they usually are. Multiple or virtual inheritance isn't as likely to work, however.
To follow on this particular subject :
How can one be sure the virtual functions in the v-table are ordered the same by different compilers ?
As long as you use interfaces with no base classes and only virtual functions, and the member function parameters are interfaces or primitive types, you should be OK. This is basically a cheap version of COM. Pretty much every Windows compiler uses the same vtable layout for this reason - compatibilty with COM interfaces.
On other platforms you only have one compiler to worry about, so it doesn't really matter.
In addition, you should not put the destructor in the interface, because this allows the user to call delete, when your function calls new, which leads to mis-matched allocations.
Instead, use reference counting, or a "dispose" method on your interface.
Instead, use reference counting, or a "dispose" method on your interface.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement