构建新库时包括库中的 header 个文件

Including header files from libraries when building a new library

明确一点: 我知道下面的示例演示了 dll-dependancy,即一个库不是 self-containe,而是依赖于另一个库来运行。

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

#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 文件。 每当我将 header Utility.h 和 link 包含在导入库中时(Utility.lib 用于 MS VS,libUtility.a 用于 g++)并且不执行 定义 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 并且还 linking 了实用程序导入库。

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

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

没有

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

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

中的函数声明

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