c++dllshared-librariesdeclspec

Including header files from libraries when building a new library


To be clear: I'm aware that the below example demonstrates a dll-dependancy, i.e. one library is not self-containe, but depends on another library to function.

Let's say I'm creating a runtime library, Utility.dll, which contains various useful functions of general nature. I create a header file Utility.h to be included in other files which need to use Utility.dll. The header file looks like

#ifndef _UTILITY_H
#define _UTILITY_H

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

DLL_EXPORT void foo();
DLL_EXPORT void foo2();
....

#endif

When I compile the source code file Utility.cpp into machine code (into Utility.dll) I make sure BUILD_DLL is defined so DLL_EXPORT gets replaced with __declspec(dllexport). This makes the functions be exported to the .dll file. Whenever I include the header Utility.h and link with the import library (Utility.lib for MS VS, libUtility.a for g++) and do not define BUILD_DLL, the function declarations in Utility.h begin with __declspec(dllimport) instead, telling the compiler that the functions are imported from a .dll (so to speak).

Now, let's say I'm also building another library, MyLibrary.dll, which wants to use some of the useful functions in Utility.dll. Similarily, I would create MyLibrary.h as

#ifndef _MYLIBRARY_H
#define _MYLIBRARY_H

#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif

DLL_EXPORT void myLibraryFunc1();
....

#endif

When I compile MyLibrary.cpp into MyLibrary.dll I'm including Utility.h and also linking against the Utility import library.

This leads us to my question: Since I define BUILD_DLL also when I compile MyLibrary.dll, this means that the function declarations in Utility.h also will read

__declspec(dllexport) void foo();
__declspec(dllexport) void foo2();
....

Not

__declspec(dllimport) void foo();
__declspec(dllimport) void foo2();

Don't we want it to be __declspec(dllimport) for the function declarations in Utility.h when we compile MyLibrary.dll, and __declspec(dllexport) for the function declarations in MyLibrary.h?


Solution

  • This is precisely the reason why you normally don't name such macros BUILD_DLL, but BUILD_UTILITY and BUILD_MYLIBRARY or similar. Likewise, the declspec macro should not be DLL_EXPORT, but UTILITY_EXPORT and MYLIBRARY_EXPORT (or perhaps UTILITY_API and MYLIBRARY_API).