How to export a C++ class from a dll? [duplicate]

Solution 1:

A common approach is to have a single macro (let's call it EXPORT) which either expands to dllimport or dllexport depending on whether some sort of "building the DLL right now" define is set, like this:

#ifdef MAKEDLL
#  define EXPORT __declspec(dllexport)
#else
#  define EXPORT __declspec(dllimport)
#endif

class EXPORT xyz {
  // ...
};

The idea is that when building your DLL, you add MAKEDLL to the preprocessor definitions. That way, all the code will be exported. Clients who link against your DLL (and hence include this header file) don't need to do anything at all. By not defining MAKEDLL, they will automatically import all the code.

The advantage of this approach is that the burden of getting the macros right is moved from the many (the clients) to just the author of the DLL.

The disadvantage of this is that when using the code above as it is, it's no longer possible to just compile the code directly into some client module since it's not possible to define the EXPORT macro to nothing. To achieve that, you'd need to have another check which, if true, defines EXPORT to nothing.

On a slightly different topic: in many cases, it's not possible (or desired!) to export a complete class like that. Instead, you may want to just export the symbols you need. For instance, in your case, you may want to just export the two public methods. That way, all the private/protected members won't be exported:

class xyz
{
public: 
    EXPORT void printing();
    EXPORT void printing(int a);
};

Solution 2:

As I remember, normally, you export not a class but a factory function that creates a new instance of class and returns a pointer. The class declaration resides in header file for compile time.

I may be wrong about the example (that was long ago), but here how it should approximately look like:

Header file (.h):

class MyClass { ... };

extern "C" DLL_API MyClass* createMyClass();

Source file (.cpp):

DLL_API MyClass* createMyClass() {
    return new MyClass();
}

Define MY_DLL_EXPORT while compiling, see foraidt's answer example.

Solution 3:

One another option:

Use the default defined macro local to the project.

You can see the default defined macros local to the project in the below location:

Properties -> C/C++ -> Preprocessor -> Preprocessor Definition.

Example:

Suppose your Project Name is: MyDLL

Default Macro Local to that project: MYDLL_EXPORTS

 #ifdef  MYDLL_EXPORTS 
    /*Enabled as "export" while compiling the dll project*/
    #define DLLEXPORT __declspec(dllexport)  
 #else
    /*Enabled as "import" in the Client side for using already created dll file*/
    #define DLLEXPORT __declspec(dllimport)  
 #endif


  class DLLEXPORT  Class_Name { 
             //.... 
  }

Solution 4:

When compiling your library you should define a macro (command line preprocessor definition), let's call it MY_DLL_EXPORT.

Then in your library's code do something like this:

#ifdef MY_DLL_EXPORT
#  define DLL_API __declspec(dllexport)
#else
#  define DLL_API __declspec(dllimport)
#endif


class DLL_API some_class { /*...*/ }