7

我有大量的代码,用 /MT 编译(即期望静态链接到 CRT)。我需要将它与使用 /MD 构建的静态第三方库结合起来(即期望动态链接 CRT)。

理论上是否可以在不重新编译的情况下将两者链接到一个可执行文件中?

如果我与 /nodefaultlib:msvcrt 链接,我最终会得到少量未定义的引用,例如__imp__wgetenv. 我很想尝试在我自己的代码中实现这些功能,转发到wgetenv等。这值得尝试,还是我会直接遇到下一个问题?

不幸的是,我被禁止将第三方代码打包到单独的 DLL 中:-/

4

3 回答 3

5

否。/MT 和/MD 是互斥的。

传递给链接器的给定调用的所有模块都必须使用相同的运行时库编译器选项(/MD/MT/LD)进行编译。

来源

于 2010-08-12T16:28:45.273 回答
2

我在 OpenSSL 源代码中找到了这样的解决方案:库的所有 obj 文件都使用组合编译:. 正如作者所描述的,这种组合允许构建静态库,能够与动态 CRT ( ) 或静态 CRT ( ) 的应用程序一起编译。/MT /Zl/MD/MT

于 2016-12-01T08:17:56.580 回答
1

我遇到过类似的情况,我有两个库,一个是用 MT 构建的,另一个是用 MD 构建的。我必须构建一个使用这两个库的功能的可执行文件。作为 MD 构建的库是第三方的,因此我无法重建它,而作为 MT 构建的库有很多依赖项,并且将所有这些作为 MD 构建是一个很大的痛苦。我从第三方配置头文件中收到错误,这使得必须将可执行文件构建为 MD。我一直在寻找将第三方 dll 打包为单独 dll 的简单方法,如问题中所述。但是,我无法以这种简单的方式在网上找到足够的解释。因此我的两分钱在下面。以下是我绕过它的方式

  1. 我构建了另一个 .dll 作为接口。该接口基本上包含了对第三方 dll 进行的所有 api 调用。此接口的头文件不包含来自第三方 dll 的任何头文件,而是所有这些头文件都包含在 interface.cpp 文件中。您期望的界面是作为 MD 构建的。
  2. 现在在我的 main.cpp 文件中,我包含了这个接口头文件,以便通过接口对第三方 dll 进行所有调用。

  3. 在将参数传递给接口时必须格外小心。int、bool 等基本变量可以作为值传递。但是,任何类或结构都需要作为 const 引用传递以避免堆损坏。这适用于偶数字符串。

如果不清楚,很高兴分享更多细节!

于 2017-09-22T22:40:44.237 回答