DLL import and export on Windows

Documents why but mainly how you need to take care of the symbol exported/imported in Windows DLL

This page explains how to take care of DLL symbol export and import easily. This is required on Windows to reuse an extension or library into an other extension. For Linux or Mac developers, this is required if you want your extension to work on Windows, although you don’t need it if you restrict yourself to your own platform.

Introduction

A dynamic library (.dll, .so, .dylib, named DLL in the following explanation) contains C++ compiled functions which might be called by another program using this DLL at runtime. When programming, as a developer you may want to reuse some classes or functions already defined and compiled in a dynamic library, or, on the other hand, you would like to make some classes / functions available within a dynamic library (for other developments).

Regarding C++ programming with dynamic libraries, DLL import / export refers to this following specification :

  • import : Using classes / methods defined in an already compiled dynamic library
  • export : Defining classes / methods to be callable in a compiled DLL

Although this mechanism only concerns Windows compilation using MSVC, as CamiTK uses the same code for all the plateforms, you will need to follow the instructions given here in order to provide a multi-plateform code.

How to export in a DLL your classes / methods in C++ ?

To make available your class or function available in a DLL, you need to use the following macro as a prefix of your class / function name :

__declspec(dllexport)

This will tell the compiler that this class / function will then be exported, which means callable from the DLL.

How to import from a DLL a class / method in C++ ?

To reuse in your C++ code an already defined and compiled class / function within a dynamic library, you will need to indicate the linker that configuration. To do so, simply declare your class / function (in the .h file, so the compiler knows them) but do not implement them (in the .cpp file) and prefix its declaration with the following macro :

__declspec(dllimport)

This way you tell the linker that this class / function is imported, which means already defined and compiled in a DLL.

How to simply import / export a class / method in CamiTK ?

Using CamiTK, if you wish to make some classes / function exportable or import some defined in an external DLL, you must include CamiTKAPI.h file and prefix all your imported / exportable classes / functions with the following macro :

CAMITK_API

How does it work ?

CamiTK uses a standard way of creating exportable macros : All files within this DLL are compiled with the COMPILE_CAMITK_API flag defined on the command line which should not be defined on any project that uses this DLL. This way any other project whose source files include this file see CAMITK_API classes / functions as being imported from a DLL, whereas this DLL sees symbols defined with this macro as being exported.

How to simply import / export a class / method in your CamiTK extension project?

In your CamiTK extension project, you may need to make some classes / function exportable or import some defined in an external DLL. For instance, you are using a component in another component or you are building your own library and want to use it in a component. In order to do that, you must create an header file MyComponentAPI.h or MyLibraryAPI.h, which defines macros which make exporting from a DLL simpler.

#if defined(_WIN32) // MSVC and mingw

    #ifdef COMPILE_MY_COMPONENT_API
        #define MY_COMPONENT_API __declspec(dllexport)
    #else
        #define MY_COMPONENT_API __declspec(dllimport)
    #endif // COMPILE_MY_COMPONENT_API

#else // for all other platforms MY_COMPONENT_API is defined to be "nothing"

        #define MY_COMPONENT_API


#endif // MSVC and mingw

In the header of the class that needs to be reused somewhere else, you can add the defined symbol:

... class MY_COMPONENT_API MyExportedClass {
...
}

Then, in the CMakeList.txt that compile the extension or library, you must specify the COMPILE_MY_COMPONENT_API flag.

camitk_extension(  COMPONENT_EXTENSION
                   HEADERS_TO_INSTALL  MyComponent.h MyComponentAPI.h
                   DEFINES COMPILE_MY_COMPONENT_API
)

In the CMakeList.txt that uses your class (for instance using the NEEDS_... keyword), you then don’t have to add anything special in order to be able to import your symbols.

Replace “MY_COMPONENT_API” by something more meaningful an relevant to your class/library (if every CamiTK developer uses “MY_COMPONENT_API” literally, that might generates some other DLL headaches!)