SiLiKhon
SiLiKhon

Reputation: 653

Check a __declspec macro in preprocessor

If I have SOME_MACRO which is defined as either __declspec(dllimport) or __declspec(dllexport), is there a way to check at compile time which one is being used?

I.e. something like this:

#if SOME_MACRO == __declspec(dllimport)
// do something
#else
// do something else
#endif

UPD. Looking at the answers I'm getting I guess I should be more specific in why I need this.

I'm trying to compile a rather big 3rd party library, which has a function declared as dllexport in most parts of their code where it's included. There's however one component in which it's a dllimport.

I need to modify the declaration slighly for the dllimport case. The switch between the two declarations is not very simple, it is a result of quite a deep tree of #ifdef instructions spread across several files. In principle I could dig this info out form these instructions, but to be sure I did it correctly I'd have to try and compile the whole library under several different configurations (each compilation taking a couple hours).

If on the other hand there was a simple way check whether their SOME_MACRO is evaluated to import or export, I could test this on a small program quickly and safely put that inside the library.

Upvotes: 0

Views: 679

Answers (2)

Baxter
Baxter

Reputation: 126

The macro is named by you the DLL creator.

  • You want a header file that works in export or import mode.
  • A C/C++ file will be used, to create a program, to build the DLL (export).
  • Other C/C++ files will be used to call the DLL (import functions).

In the build implementation file a macro, that you name, is defined before the inclusion of the header. e.g.

#define DLLNAME_BUILD_DLL
#include "dll_header.h"

In the header, if the macro is defined, the mode is set to export. When using the DLL the macro is not defined and the functions are imported.

Upvotes: 0

R Sahu
R Sahu

Reputation: 206557

You cannot use

#if SOME_MACRO == __declspec(dllimport)

__declspec(dllimport) is not a valid token for a preprocessor expression.

Your best option is to use another preprocessor macro, such as:

// Are we building the DLL?
#if defined(BUILD_DLL)
   // Yes, we are.
   #define SOME_MACRO __declspec(dllexport)
#else
   // No. We are using the DLL
   #define SOME_MACRO __declspec(dllimport)
#endif

Now, you can use:

#if defined(BUILD_DLL)

to include conditional code depending on whether you are building the DLL or using the DLL.


Practically speaking, that ends to be a little bit more involved.

  1. Most projects have more than one DLL. BUILD_DLL is not going to work. You will need BUILD_xxx_DLL for each DLL you build. Let's say you have two DLLs, utility and core. and an application that depends on both.

  2. You may also need to create a static library.

You will need something like the following in every public .h file of the utility library.

#if defined(BUILD_UTILITY_STATIC)
   #define UTLIITY_EXPORT
#elif defined(BUILD_UTILITY_DLL)
   #define UTLIITY_EXPORT__declspec(dllexport)
#else
   #define UTLIITY_EXPORT__declspec(dllimport)
#endif

Of course, you don't want to have to repeat the same code in lots of .h files. You will create a .h file that contains the above and #include that in all other .h files.

When building utility.dll, you will need to define BUILD_UTILITY_DLL and leave BUILD_UTILITY_STATIC undefined.

When building utllity.lib (static library), you will need to define BUILD_UTILITY_STATIC and leave BUILD_UTILITY_DLL undefined.

Users of utility.dll will leave BUILD_UTILITY_STATIC as well as BUILD_UTILITY_DLL undefined.

Users of utility.lib (static library) will need to define BUILD_UTILITY_STATIC and leave BUILD_UTILITY_DLL undefined.

You will need a similar file for core.dll and core.lib.

Upvotes: 3

Related Questions