1

明确一点:我知道下面的示例演示了 dll 依赖关系,即一个库不是自包含的,而是依赖于另一个库来运行。

假设我正在创建一个运行时库 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.dll 时,我们不希望 Utility.h 中的函数声明为 __declspec(dllimport),而 MyLibrary.h 中的函数声明为 __declspec(dllexport) 吗?

4

1 回答 1

2

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

于 2015-07-09T19:36:13.360 回答