0

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.

SiLiKhon
  • 583
  • 4
  • 15
  • `__declspec` isn't a macro, it's a special keyword in the Visual C++ (and compatible) compilers. – Some programmer dude Jan 19 '18 at 22:06
  • Use the same logic that is determining the value of SOME_MACRO? – Anon Mail Jan 19 '18 at 22:10
  • @Someprogrammerdude thanks for the comment and sorry for mixing up the terms. Still, I guess the idea of what I want to be able to check should be clear. – SiLiKhon Jan 19 '18 at 22:11
  • @AnonMail in principle, that's an option. But that logic was implemented by someone else and is kinda complicated, so I was hoping there might be an easy way to check this at compile time. – SiLiKhon Jan 19 '18 at 22:13

2 Answers2

3

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.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thanks for the suggestion. This `BUILD_DLL` logic is implemented by someone else in my case. And it's a bit too complicated, so I was hoping maybe I could stringify `SOME_MACRO` and then check, or something... – SiLiKhon Jan 19 '18 at 22:17
  • @SiLiKhon, that sounds promising. You can dig a bit and figure out the equivalent of `BUILD_DLL`. You can use that macro to include your conditional code. – R Sahu Jan 19 '18 at 22:33
0

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.

Baxter
  • 126
  • 4