#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?
__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) .
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.
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.
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
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.
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.
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)
.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With