为其他人生成 C++ 静态或动态库时的最佳实践?

Best practice when producing a C++ static or dynamic library for others?

我正在为我公司的其他客户提供 Microsoft C++ 库(静态和动态)。我的库有一些 class 依赖于位于公共 Windows DLL 中的函数,这些 DLL 的导入库 没有 包含在项目 link 设置中默认情况下。

每次出现这样的新依赖项时,与其在我的库的每个构建配置的 linker 部分添加一个新的导入库名称,我认为在封装方面会更好如果我在依赖于此类 DLL 的函数的 class 的 .cpp 文件中使用 #pragma comment(lib, ...),则依赖项(以及更多的自我记录),例如:

Foo.cpp:

#include <SomeWinLib.h>

#pragma comment(lib, "somewinlib.lib")

... implementation of Foo class ...

...但我发现如果我图书馆的客户也在使用 SomeWinLib,这会导致 link warnings/errors。在对该主题进行了一些阅读之后,recommended/best 实践似乎是让在我的库中 linking 的客户端也在它所依赖的库中 link。

我仍然希望这对客户来说尽可能 automatic/painless,所以而不是仅仅将所需导入库的列表放在 readme.txt 文件中(然后坐下来等待不可避免的 phone 来自沮丧的开发人员的调用),我只是将 #pragma comment 放在 Foo.h 头文件 中。这样,如果客户端包含需要它的 class 的头文件,它们将自动 link 在所需的库中。

Foo.h:

#pragma comment(lib, "somewinlib.lib")

public class Foo
{

但是,当我构建我的库时,Foo.cpp 显然包括 Foo.h,所以我似乎需要某种预处理器 "guard" 在 #pragma comment 行周围在头文件中,以便只有在客户端包含我的头文件时预处理器才能看到它。

Foo.h:

#if !defined(building_my_library)
  #pragma comment(lib, "somewinlib.lib")
#endif

public class Foo
{

所有这些似乎几乎每个图书馆都必须做的事情,但是当我 Google 其他开源 Windows 图书馆时,我没有看到这样的例子。这让我怀疑我错过了什么地方。

有谁知道我是否正确理解了这些问题,如果是这样,我是否使解决方案过于复杂了?

谢谢!

一个您可能没有考虑过的解决方案是通过 LoadLibraryGetProcAddress 使用到 DLL 的运行时链接,消除对 somewinlib.lib[= 的依赖15=].

你的最后一个选择或多或少是 boost headers 所做的,除了它们还提供了一个预处理器指令来显式关闭 auto-linking 以防你想自己控制事情:

#if !defined(building_my_library) && !defined(no_auto_link_stuff)
    #pragma comment(lib, "somelib.lib")
#endif