在构建新库时包含库中的头文件

时间:2015-07-09 19:09:06

标签: c++ dll shared-libraries declspec

要明确: 我知道下面的例子演示了一个dll-dependancy,即一个库不是自包含的,但依赖于另一个库来运行。

假设我正在创建一个运行时库,Utility.dll,它包含一般性的各种有用功能。 我创建一个头文件Utility.h,以包含在需要使用Utility.dll的其他文件中。 头文件看起来像

#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

当我将源代码文件Utility.cpp编译成机器代码(进入Utility.dll)时,我确保定义了BUILD_DLL,因此DLL_EXPORT被__declspec(dllexport)替换。这使得函数可以导出到.dll文件。 每当我包含头部Utility.h并链接到导入库(MS VS的Utility.lib,g ++的libUtility.a)并且定义BUILD_DLL时,Utility.h中的函数声明开始于改为__declspec(dllimport),告诉编译器函数是从.dll导入的(可以这么说)。

现在,假设我还在构建另一个库MyLibrary.dll,它希望使用Utility.dll中的一些有用功能。类似地,我将创建MyLibrary.h作为

#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

当我将MyLibrary.cpp编译成MyLibrary.dll时,我包括Utility.h,并且还链接到Utility导入库。

这会引导我们进入问题: 由于我在编译MyLibrary.dll时也定义了BUILD_DLL,这意味着Utility.h中的函数声明也会读取

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

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

当我们为MyLibrary.h编译MyLibrary.dll和__declspec(dllexport)中的函数声明时,我们不希望它是__declspec(dllimport)吗?

1 个答案:

答案 0 :(得分:2)

这正是您通常不会命名此类BUILD_DLL,而是BUILD_UTILITYBUILD_MYLIBRARY或类似名称的原因。同样,declspec宏不应该是DLL_EXPORT,而是UTILITY_EXPORTMYLIBRARY_EXPORT(或者UTILITY_APIMYLIBRARY_API)。