Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top