【问题标题】:mixing code compiled with /MT and /MD混合使用 /MT 和 /MD 编译的代码
【发布时间】:2011-03-29 01:03:17
【问题描述】:

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

理论上是否可以将两者链接成一个可执行文件而无需重新编译?

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

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

【问题讨论】:

    标签: visual-c++ build msvcrt


    【解决方案1】:

    没有。 /MT 和 /MD 是互斥的。

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

    Source

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

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

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

        如果不清楚,很乐意分享更多细节!

        【讨论】:

          最近更新 更多