1

With C++, i'm trying to use a class declared on my main program instance to be used with on DLL. It's a lot of examples to a class from DLL to use on main program, but I need the other way. For now, a simple declaration is ok, but my next step will be use a static class from main program on DLL.

For knowledge, I'm using MinGW 3.4.5 on Windows 10.

For an example I'm trying to generate 3 files:

  • tst_class.lib
  • tst_library.dll
  • tst.exe

And the source code files are:

  • tst_class.h
class ON_MAIN tst_class {
public:
     tst_class(char *);
    ~tst_class(void);
};
  • tst_class.c
#include <stdio.h>

#define ON_MAIN  __declspec(dllexport)
#define ON_DLL   __declspec(dllimport)

#include "tst_class.h"

tst_class::tst_class(char *source)
{
    printf("new tst_class() from %s\n", source);
}
tst_class::~tst_class(void)
{
    printf("delete (tst_class *)\n");
}
  • tst_library.c
#include <windows.h>

#define ON_MAIN  __declspec(dllimport)
#define ON_DLL   __declspec(dllexport)

#include "tst_class.h"

ON_DLL void tst(void)
{
    tst_class *t = new tst_class("library");
    delete t;
}
  • tst.c
#include <stdio.h>
#include <windows.h>

#define ON_MAIN  __declspec(dllexport)
#define ON_DLL   __declspec(dllimport)

#include "tst_class.h"

typedef void (__cdecl *f_pointer)(void);

int main(int argc, char **argv)
{
    tst_class *t = new tst_class("main");
    delete t;

    HMODULE module = LoadLibrary("tst_library.dll");

    if(module != NULL) {
        printf("Dll loaded\n");

        void *function_pointer = (void *)GetProcAddress(module, "tst");

        if(function_pointer != NULL) {
            f_pointer function = (f_pointer)function_pointer;

            function();
        }

        FreeLibrary(module);
    } else {
        printf("Can't load dll\n");
    }

    return 0;
}

To compile them:

  • g++ -c tst_class.c -o tst_class.o OK
  • ar cr tst_class.lib tst_class.o OK
  • g++ tst_library.c tst_class.lib -o tst_library.dll -shared Error

And here I've got this error message:

.../ccpg0mO9.o:tst_library.c:(.text+0x5a): undefined reference to '_imp___ZN9tst_classC1EPc' .../ccpg0mO9.o:tst_library.c:(.text+0xb4): undefined reference to '_imp___ZN9tst_classD1Ev'

But following to the last step...

  • g++ tst.c tst_class.lib -o tst.exe OK

What I'm doing wrong with compiling/linking the library?

The executable works well. Not loading the library of cource, because it not exists.

Gangrel
  • 85
  • 1
  • 7

1 Answers1

1

Your defines are not quite right. The form of the declspec is generally

#if BUILDING_MYDLL
  #define MYDLL_EXPORT  __declspec(dllexport)
#else
  #define MYDLL_EXPORT  __declspec(dllimport)
#endif

And for the definition of the class

class MYDLL_EXPORT tst_class {
public:
     tst_class(char *);
    ~tst_class(void);
};

Then when building and linking the dll code, you use a command line define for BUILDING_MYDLL (e.g. -D BUILDING_MYDLL) or you define BUILDING_MYDLL in a header file that is internal to the dll (e.g. in Visual Studio based solutions that was often stdafx.h).

Here is another answer that is related.

Community
  • 1
  • 1
Niall
  • 30,036
  • 10
  • 99
  • 142
  • Ok. I got this. My problem with `undefined reference` is gone. Now I can do more tests, but what I figured out is: the class code is on the .lib file. What I want is the class code is on the main program, and with new versions, the DLL will use the new class source. – Gangrel Nov 05 '15 at 13:11
  • Good, I'm glad it works. That sounds like a new question. Write it up with the code samples, expected outcomes etc. and post it as a new question. – Niall Nov 05 '15 at 13:15
  • I'll make another question. But the solution is only for the `undefined reference`. The main question is: Use class (code) from main program on DLL. – Gangrel Nov 05 '15 at 15:28
  • Explore pure virtual base classes as an interface. You may need to shift them into a third dll that will be shared with both the current dll and the exe. – Niall Nov 05 '15 at 18:57