15
#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

Community
  • 1
  • 1
Blub
  • 13,014
  • 18
  • 75
  • 102
  • Seems that you have some strange mistake somewhere that is not mentioned here. Rest assured, it should work, DLLs are very useful. – Öö Tiib Feb 20 '13 at 16:06
  • see https://learn.microsoft.com/en-us/cpp/build/importing-into-an-application-using-declspec-dllimport?view=vs-2019 – GreatAndPowerfulOz Oct 01 '20 at 14:51

7 Answers7

21

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
SridharKritha
  • 8,481
  • 2
  • 52
  • 43
  • It's a shame that the most useful code to copy in this question isn't in the accepted answer. At least you have it here for us :) – kayleeFrye_onDeck Nov 06 '18 at 05:18
  • @kayleeFrye_onDeck that code is already in question. – Öö Tiib Jul 28 '20 at 16:04
  • Once I have created a dll, still when using it in another project, MYDLL_EXPORTS remains set while it should be unset here. Could somebody please let me know why this is happening?? – aki_sud Apr 05 '21 at 14:36
13

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.

Öö Tiib
  • 10,809
  • 25
  • 44
  • 1
    I added COMPILING_DLL to the preprocessor definitions, but it's still complaining "error C2491: 'test2' : definition of dllimport function not allowed". Which makes no sense, because Visual Studio even grays out the correct one now. I added a screenshot to illustrate this. – Blub Feb 20 '13 at 13:29
  • You should add that COMPILING_DLL to preprocessor definitions of your DLL project. If you have that header included in precompiled header of that project, make sure you rebuild it. – Öö Tiib Feb 20 '13 at 16:00
2

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

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).

Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
2

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

Gabriel Devillers
  • 3,155
  • 2
  • 30
  • 53
1

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.

Masood Khaari
  • 2,911
  • 2
  • 23
  • 40
  • The source of compiler error you have mentioned ("error C2491: 'test2' : definition of dllimport function not allowed") was this. But it seems it can be solved by explicitly using `#define COMPILING_DLL` in code instead of adding it to: Project>properties>C/C++>Preprocessor>Preprocessor Definitions – Masood Khaari Feb 20 '13 at 14:44
1

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.