views:

384

answers:

4

How to create some class from dll(constructor in dll)?(с++) or how to dynamically load class from dll?

+2  A: 

You will need to export a function from the DLL that calls on to the constructor and returns the new object.

Try to avoid using concrete C++ types as function parameters; the idea of DLLs is that you can independently update them, but an upgraded compiler may lay out std::string differently, causing incompatibility at runtime.

This is what is at the root of COM, for example - a limited type system and a standard exported function for getting instances of objects.

Daniel Earwicker
Tt sounds as if the DLL's source is not under his control.
Frank Bollack
DLL source is under my control
SomeUser
If the class is intended to be used, then it should probably already be compiled with __declspec(dllexport), so then it is only a matter of convincing the header file to put __declspec(dllimport) in the class definition. If not, you can always modify the header file yourself.
JesperE
+5  A: 

You need to declare your class using the __declspec(dllexport) keyword when building the DLL. When using the DLL, the class needs to be declared with __declspec(dllimport):

#ifdef COMPILING_DLL
#define DECLSPEC_CLASS __declspec(dllexport)
#else
#define DECLSPEC_CLASS __declspec(dllimport)
#endif

class DECLSPEC_CLASS MyClass
{
...
}

When the DLL is compiled, you should add -DCOMPILING_DLL to the list of defines.

When using the class, you must statically link with the DLL, i.e. pass the import library mydll.lib to the main program.

If you want to load the DLL at runtime, you need to have a C-function in the DLL which creates a object and returns it for you. There is no way to lookup a constructor dynamically in a DLL (using GetProcAddress()).

JesperE
Can you quote a source for the last statement? AFAIK a ctor has a mangled name, and you can call GetProcAddress using that name. What would stop you?
MSalters
Yes, technically you're right.
JesperE
+1  A: 

Answering your question strictly, you need to add an extern "C" function that returns the result of the constructor:

extern "C" foo* __declspec(dllexport) new_foo(int x) {
    return new foo(x);
}

Then in your source you can use GetProcAddr on "new_foo" to call the function.

jmucchiello
+2  A: 

Instead of exporting every method of the class using __declspec, you can also rely on the fact that the compiler can invoke virtual functions via the vtable, so for example:

//note: no __declspec
class IPublicInterface
{
  virtual ~IPublicInterface() = 0;
  virtual void SomeMethod() = 0;
};

//note: no __declspec
class SomeClass : IPublicInterface
{
  virtual ~SomeClass() { ... }
  virtual void SomeMethod() { ... }
};

//note: this is the only method which needs to be exported from the DLL
IPublicInterface* createSomeClass()
{
  return new SomeClass();
}
ChrisW