What does #ifdef WIN32DLL_EXPORTS mean? - c++

I've created a DLL a file, and in the header file I see :
#ifdef WIN32DLL_EXPORTS
I don't understand what does it mean and where/how we can set up WIN32DLL_EXPORTS.
if I use:
#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif
WIN32DLL_API int testSum(void);
testSum is considered as __declspec(dllimport). So I think my project is not set to WIN32DLL_EXPORTS? How can I change this?

There is a comment block immediately above the line you quoted. Read it.
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the WIN32DLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// WIN32DLL_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif

You can either:
define WIN32DLL_EXPORTS in the project's Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor definitions.
if you use a precompiled header (e.g. stdafx.h) then you can also define WIN32DLL_EXPORTS
there with a #define statement.

Related

C++ Unresolved external symbol - library problem?

Sorry if the question is dumb, I'm still a noobie.
I've got a header and a .lib file. I've included the header and set up the library file in the linker additional libraries directory, however I keep getting unresolved external symbol error over the functions defined in the header (which should be included in the library).
On the top of the header the following is written:
#pragma once
// To use the framework define _WINDOWS in project's settings!
#if defined(_WINDOWS)
#if defined(FRAMEWORK_PROJECT)
#define FRAMEWORK_API extern "C" __declspec(dllexport)
#else
#define FRAMEWORK_API extern "C" __declspec(dllimport)
#endif
#else
#define FRAMEWORK_API
#endif
Where would I need to define _WINDOWS variable, and what to? (Visual Studio) or is the problem something different entirely?

What are the different ways with which we can dynamically Link a DLL

I want to link a .dll dynamically.
What are the multiple ways to do so?
One way I know, is by using HMODULE WINAPI LoadLibrary(_In_ LPCTSTR lpFileName)
function.
Is there any other way?
I am trying to understand the below code:
#if defined WIN32
// We want to define DTE_DLL_EXPORT if we are making
// a dll, but not if we are making a static library...
#if defined DTE_STATIC
#define GFITDTE_ENTRYPT
#else
#if defined _GFITDTE_BUILD_
#define GFITDTE_ENTRYPT __declspec(dllexport)
#else
#if defined DTE_IMPORT
#define GFITDTE_ENTRYPT __declspec(dllimport)
#else
#define GFITDTE_ENTRYPT
#endif
#endif
#endif
#else // Not WIN32
Can some on explain the above code??
The code shown has nothing to do with LoadLibrary. It's typical for header files, which in turn means you're building a DLL that's NOT supposed to be loaded via LoadLibrary. Instead, the compiler knows the function prototypes from the header, and the linker uses an import library to set up the DLL linking.

Where do I create preprocessor directives for a dll export?

I am creating a c++ dll to be imported in vb.net.
I have found that the best way to organize the imports and exports in the header file of the dll, is something of the following type:
#ifndef MY_DLL_EXPORTS
#define MY_DLL_EXPORT __declspec(dllexport)
#else
#define MY_DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
MY_DLL_EXPORT BOOL my_function(uint32_t x);
#ifdef __cplusplus
}
#endif
My question is, where are the __cplusplus and MY_DLL_EXPORTS supposed to be defined ?
I have not done this before and I can't seem to find a place in the code for it. I read something about putting these definitions in the
Project Properties -> Configuration Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions
Do I put them in the DLL's project properties ? and if i do, on using this DLL, will they always be defined so the if statement will always go to the dllimport ?
Also, is __cplusplus already defined or must I define it ?
__cplusplus is defined for you by a C++ compiler, but NOT by a C compiler. This is how you can determine if your code is being compiled by a C or C++ compiler. That's why this is used to guard the extern "C" construct. A C compiler would just omit it (since it emits C linkage already).
The other constants can be either defined on the compiler's command line (eg. in the menu you listed), or in the code somewhere:
#define MY_DLL_EXPORTS
Best place to define COMPILING_DLL 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.

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

Alternatives for empty macros

In my C++ header file, I have the following:
#ifdef _DLL
#define DLL_API __declspec(dllexport) // Being compiled as a DLL.
#else
#define DLL_API // Not being compiled as a DLL.
#endif
Later on, I have things like:
DLL_API int GetNumber();
I'm oversimplifying, but the basic question here is whether there's a way to get the compiler to just skip over DLL_API if it's not defined.
No.
When DLL_API is defined as preprocessor macro that contains nothing then preprocessor replaces DLL_API with nothing and compiler will see nothing there. If it is undefined for preprocessor then preprocessor does nothing with it. Then compiler will see it unchanged and you get compiler error about unknown identifier DLL_API, because such thing is not part of C++ language.
Attributes like __declspec() are platform specific extensions and it is common convention to wrap their usage in interfaces into preprocessor macros.
Usually, it is
#ifdef _WIN32
#ifdef _DLL
#define DLL_API __declspec(dllexport) // Being compiled as a DLL.
#else
#define DLL_API __declspec(dllimport) // Not being compiled as a DLL.
#endif
#else
#define DLL_API
#endif
so that it is portable, and DLL_API is always transformed into something valid.