构建新库时包括库中的 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_UTILITY
和 BUILD_MYLIBRARY
或类似名称的原因。同样,declspec 宏不应该是 DLL_EXPORT
,而是 UTILITY_EXPORT
和 MYLIBRARY_EXPORT
(或者可能是 UTILITY_API
和 MYLIBRARY_API
)。
明确一点: 我知道下面的示例演示了 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_UTILITY
和 BUILD_MYLIBRARY
或类似名称的原因。同样,declspec 宏不应该是 DLL_EXPORT
,而是 UTILITY_EXPORT
和 MYLIBRARY_EXPORT
(或者可能是 UTILITY_API
和 MYLIBRARY_API
)。