2

当我需要构建一些第三方库以在不同版本的 MSVC 下的多个项目中使用时,我通常为每个MSVC 版本以及调试和发布配置构建它。这就是 boost 所做的,这就是我们在团队中的整个一生都在做的事情。

但是,我仍然不明白,为什么我不能用 like... 来构建这个库。我只需要函数原型和目标代码,对吗?由于我静态链接 CRT,我没有外部依赖项。但是,当我尝试将在 MSVC8 下的 Release 中构建的库与我在 MSVC10 下的 Debug 中的项目链接时,我遇到了这个令人讨厌的“已定义”链接器错误,我们都非常讨厌。

但为什么?我可以在 lib 中“封装”所有这些函数而不导出它们,以便我的项目只从 lib 中获取它需要的东西吗?为什么我可以拥有可以在每个项目中链接的 libpng 和 zlib 的预编译版本?是的,我猜它们不是使用 MSVC 构建的,但仍然使用 CRT 的相同功能。那么任何人都可以深入解释或分享对这个问题的一些开明解释的链接吗?

4

1 回答 1

3

由于我静态链接 CRT,我没有外部依赖项

好吧,那不是真的,你确实有依赖。关于 CRT 的静态版本。调试或发布,取决于您的构建设置。它是一个外部依赖项,链接器稍后会在链接库时粘合 CRT。使用该库的代码也依赖于 CRT。如果编译设置不匹配,那么链接器会出错。

您可以通过构建 DLL 而不是静态链接库来隔离该依赖关系。您必须进一步确保导出的函数不会导致 CRT 依赖。您不能从标准 C++ 库返回 C++ 对象,也不能返回指向需要由客户端代码释放的对象的指针。甚至传递结构也很棘手,因为它们的打包是一个实现细节,但您通常会侥幸成功。一个很好的实际示例是 COM 自动化,它迫使您使用通用类型的子集。Windows 充斥着它们,所有这些服务器都可以与任何版本的编译器或 CRT 一起使用。甚至任何语言。然而,这是有代价的,编写这样的库并不像在静态库中扔一堆代码那样简单或方便。

于 2012-03-15T15:51:39.363 回答