How can I import dll of a C++ class inside a namespace
Solution 1
If you're trying to instantiate a class, then you need to know its structure on compilation time. You can achieve this by creating an abstract class that defines the instance methods that the imported class will have to redefine. For example:
//interface.h
class TestInterface
{
public:
virtual void Function( int ) = 0;
virtual int getBar(void) = 0;
};
Afterwards, in your DLL, you can include interface.h, inherit TestInterface and redefine the pure-virtual methods:
//test.h
namespace DllTest {
class Test : public TestInterface
{
public:
Test();
void Function( int );
int getBar(void);
private:
int bar;
};
};
You could then define a function in your DLL which allocates a Test object:
extern "C" __declspec(dllexport) TestInterface *allocate_test() {
return new DllTest::Test();
}
And finally, when you import the DLL, look for the symbol "allocate_test" and use it:
TestInterface *(*test_fun)() = (TestInterface *(*test_fun)())GetProcAddress(hInstLibrary,"allocate_test");
TestInterface *test_ptr = test_fun();
test_ptr->Function(12); //use you object
Solution 2
First, note that this is a Microsoft particularity. Different rules will hold for other systems.
Writing things as you did doesn't work, or at least, is painful. You
need to use __declspec(dllexport)
in the DLL which defines the
functions, but __declspec(dllimport)
when compiling code which invokes
the functions from another DLL. The usual way of handling this is to
use some specific macro name specifying the DLL, and do something like:
#ifdef __WIN32
#ifdef MYMODULE_DLL
#define MYMODULE_EXPORT __declspec(dllexport)
#else
#define MYMODULE_EXPORT __declspec(dllimport)
#endif
#else
#define MYMODULE_EXPORT
#endif
Put this in a header which is included in all of the headers in your
DLL, and define MYMODULE_DLL
on the command line of the project.
Also, it's possible to export an entire class:
class MYMODULE_EXPORT DllTest
{
// ...
};
This has the effect of exporting or importing all of the functions and static members of the class.
Comments
-
accfews almost 2 years
I read some documents which gives simple examples on functions compatible with C.
__declspec(dllexport) MyFunction();
I'm okey with that. I write a small application uses the functions of this dll. I used explicit linking with
LoadLibrary()
function. C style functions work without problems. But when i write my class as
namespace DllTest { class Test { public: __declspec(dllexport) Test(); __declspec(dllexport) void Function( int ); __declspec(dllexport) int getBar(void); private: int bar; }; } #endif
it compiles well and Dll is created. While working with C style functions i was simply taking a function pointer from LoadLibrary() and GetProcAddress(...) functions.
My previous usage is
typedef void (*Function)(int); int main() { Function _Function; HINSTANCE hInstLibrary = LoadLibrary(TEXT("test.dll")); if (hInstLibrary) { _Function = (Function)GetProcAddress(hInstLibrary,"Function"); if (_Function) { // use the function
But now i have no idea how can i instantiate my class? How can i use explicit linkage or implicit linkage?
Any help with a code sample would be appreciated.
-
accfews about 12 yearsI have this piece in my code, while putting here i ripped that part. Still doesn't help with creating and using instances of my class, while importing.
-
James Kanze about 12 yearsOK. I just noticed that you're using
GetProcAddress
. Which means that the functions can't be member functions, onlyextern "C"
(otherwise, you can't name them). You'll have to define an abstract interface, and anextern "C"
function which returns an instance. -
James Kanze about 12 yearsTwo points: first, the
TestInterface
doesn't need (nor should it have) the private data member, and second, if he's going to pass the name of the function toGetProcAddress
, the function had best beextern "C"
(otherwise, he has to pass the mangled name). And of course, inallocate_test
, you meant to doreturn new Test;
, notreturn new TestInterface();
(which won't compile).