Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro for dllexport/dllimport switch

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

How / where do I define COMPILING_DLL ?

Seen here: what does __declspec(dllimport) really mean?

Sounds like I can't use load-time dynamic linking at all if I can't use the same header?

enter image description here

like image 303
Blub Avatar asked Feb 20 '13 13:02

Blub


People also ask

What does __ Declspec Dllimport mean?

__declspec(dllimport) is a storage-class specifier that tells the compiler that a function or object or data type is defined in an external DLL. The function or object or data type is exported from a DLL with a corresponding __declspec(dllexport) .

Is __ Declspec Dllimport necessary?

Using __declspec(dllimport) is optional on function declarations, but the compiler produces more efficient code if you use this keyword. However, you must use __declspec(dllimport) for the importing executable to access the DLL's public data symbols and objects.

What is Dllimport and Dllexport?

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. You can use them to export and import functions, data, and objects to or from a DLL.


7 Answers

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
like image 70
SridharKritha Avatar answered Oct 03 '22 23:10

SridharKritha


Best place to define COMPILING_DLL=1 is command line of compiler. If you use Visual Studio IDE then it is in Project properties ... C/C++ ... Preprocessor ... Preprocessor Definitions.

__declspec(dllimport) is Microsoft specific extension to C++. Microsoft has excellent online documentation.

like image 39
Öö Tiib Avatar answered Oct 03 '22 23:10

Öö Tiib


In the DLL project, you add a #define (either in a header file or in the project properties) for COMPILING_DLL. As this will not be set for any other project (especially if you name it something better than COMPILING_DLL) then the #if directive will work properly.

like image 31
Some programmer dude Avatar answered Oct 04 '22 00:10

Some programmer dude


You (actually Visual Studio in ideal cases) defines the COMPILING_DLL as an argument to the compiler when you build the DLL. So, it will default to __declspec(dllexport). On the other end, when you USE the DLL's header file, you don't define this, so DLLEXPORT will be evaluated by default to __declspec(dllimport).

like image 20
Ferenc Deak Avatar answered Oct 04 '22 00:10

Ferenc Deak


You can't define function body that way in the header file. It is prohibited by __declspec(dllimport). This specifier can only be specified on function declaration, not definition.

You have to move the function body to a source file.

in header file:

extern DLLEXPORT void test2();

In .cpp file:

void test2()
{
   // ...
}

As folks said, don't forget to add COMPILING_DLL to the project preprocessor definitions.

like image 24
Masood Khaari Avatar answered Oct 04 '22 01:10

Masood Khaari


Actually, the real problem is the preprocessor directive. You should use #ifdef and not #if to test if the variable is really defined (and we don't care about the defined value or if there is any).

NOTE: I know this thread is 1-year old but it still may be useful for somebody who have this problem in the future.

like image 34
Manuel Garnier Avatar answered Oct 04 '22 00:10

Manuel Garnier


If you use CMake to generate your build configuration, you should be able to use the macro <projectname>_EXPORTS the way you want to use COMPILING_DLL, where projectname was defined with the CMake command project(projectname):

A preprocessor macro, <target_name>_EXPORTS is defined when a shared library compilation is detected.

source

I tested and it works on Windows using the Ninja generator with compiler MSVC from Visual Studio 2015 Express.

Related: CMake adds -Dlibname_EXPORTS compile definition

like image 41
Gabriel Devillers Avatar answered Oct 04 '22 01:10

Gabriel Devillers