How can I import dll of a C++ class inside a namespace

10,608

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.

Share:
10,608
accfews
Author by

accfews

Software Developer

Updated on June 05, 2022

Comments

  • accfews
    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
    accfews about 12 years
    I 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
    James Kanze about 12 years
    OK. I just noticed that you're using GetProcAddress. Which means that the functions can't be member functions, only extern "C" (otherwise, you can't name them). You'll have to define an abstract interface, and an extern "C" function which returns an instance.
  • James Kanze
    James Kanze about 12 years
    Two 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 to GetProcAddress, the function had best be extern "C" (otherwise, he has to pass the mangled name). And of course, in allocate_test, you meant to do return new Test;, not return new TestInterface(); (which won't compile).