142

在 Visual Studio 中,有编译标志 /MD 和 /MT 可让您选择所需的 C 运行时库。

我理解实现上的差异,但我仍然不确定使用哪一个。有什么优点/缺点?

我听说 /MD 的一个优点是,它允许某人更新运行时,(比如可能修补安全问题)并且我的应用程序将从这次更新中受益。尽管对我来说,这似乎是一个非功能:我不希望人们在不让我针对新版本进行测试的情况下更改我的运行时!

我很好奇的一些事情:

  • 这将如何影响构建时间?(大概 /MT 有点慢?)
  • 其他影响是什么?
  • 大多数人使用哪一种?
4

7 回答 7

96

通过与 /MD 动态链接,

  • 您会接触到系统更新(无论好坏),
  • 您的可执行文件可以更小(因为它没有嵌入库),并且
  • 我相信至少 DLL 的代码段在所有积极使用它的进程之间共享(减少消耗的 RAM 总量)。

我还发现,在实践中,当使用使用不同运行时选项构建的静态链接的 3rd 方仅二进制库时,主应用程序中的 /MT 往往比 /MD 更容易引起冲突(因为你如果 C 运行时被多次静态链接,特别是如果它们是不同的版本,则会遇到麻烦)。

于 2009-04-16T18:49:54.403 回答
44

如果您使用的是 DLL,那么您应该使用动态链接的 CRT (/MD)。

如果您为 .exe 和所有 .dll 使用动态 CRT,那么它们都将共享一个 CRT 实现——这意味着它们都将共享一个 CRT 堆,并且在一个 .exe/.dll 中分配的内存可以在其他。

如果您对 .exe 和所有 .dll 使用静态 CRT,那么它们都将获得 CRT 的单独副本 - 这意味着它们都将使用自己的 CRT 堆,因此必须在它所在的同一模块中释放内存被分配。您还将遭受代码膨胀(CRT 的多个副本)和过多的运行时开销(每个堆从操作系统分配内存以跟踪其状态,并且开销可能很明显)。

于 2009-09-04T07:11:58.447 回答
25

我相信通过 Visual Studio 构建的项目的默认设置是 /MD。

如果您使用 /MT,您的可执行文件将不依赖于目标系统上存在的 DLL。如果您将它包装在安装程序中,它可能不会成为问题,您可以采用任何一种方式。

我自己使用 /MT,这样我就可以忽略整个 DLL 的混乱。

PS 正如Fooz 先生所指出的,保持一致至关重要。如果您要与其他库链接,则需要使用与它们相同的选项。如果您使用第三方 DLL,几乎可以肯定您需要使用运行时库的 DLL 版本。

于 2009-04-16T18:28:13.567 回答
15

我更喜欢用/MT 静态链接。

即使您确实使用 /MD 获得了一个较小的可执行文件,您仍然必须提供一堆 DLL 以确保用户获得正确的版本来运行您的程序。最后,您的安装程序将比与 /MT 链接时更大。

更糟糕的是,如果您选择将运行时库放在 windows 目录中,用户迟早会安装具有不同库的新应用程序,如果运气不好,会破坏您的应用程序。

于 2009-04-16T18:59:20.497 回答
8

您在使用 /MD 时会遇到的问题是 CRT 的目标版本可能不在您的用户计算机上(尤其是如果您使用的是最新版本的 Visual Studio 并且用户的操作系统较旧)。

在这种情况下,您必须弄清楚如何将正确的版本安装到他们的机器上。

于 2009-04-16T19:00:54.470 回答
7

来自http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx

/MT 定义 _MT 以便从标准头 (.h) 文件中选择运行时例程的多线程特定版本。此选项还会导致编译器将库名称 LIBCMT.lib 放入 .obj 文件中,以便链接器将使用 LIBCMT.lib 来解析外部符号。创建多线程程序需要 /MT 或 /MD(或它们的调试等效项 /MTd 或 /MDd)。

/MD 定义 _MT 和 _DLL 以便从标准 .h 文件中选择运行时例程的多线程和 DLL 特定版本。此选项还会导致编译器将库名称 MSVCRT.lib 放入 .obj 文件中。

使用此选项编译的应用程序静态链接到 MSVCRT.lib。该库提供了一层代码,允许链接器解析外部引用。实际工作代码包含在 MSVCR71.DLL 中,必须在运行时对与 MSVCRT.lib 链接的应用程序可用。

当 /MD 与定义的 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 一起使用时,它将导致应用程序链接到静态多线程标准 C++ 库 (libcpmt.lib) 而不是动态版本 (msvcprt.lib),同时仍通过动态链接到主 CRT msvcrt.lib。

因此,如果我正确解释它,则/MT静态链接和/MD动态链接。

于 2009-04-16T18:33:38.013 回答
2

如果您正在构建使用其他 dll 或库的可执行文件,则首选 /MD 选项,因为这样所有组件都将共享同一个库。当然,这个选项应该匹配所有涉及的模块,即 dll/lib/exe。

如果您的可执行文件不使用任何 lib 或 dll,而不是任何人的调用。现在差异不是太大,因为共享方面没有发挥作用。

因此,也许您可​​以使用 /MT 启动应用程序,否则没有令人信服的理由,但是当需要添加 lib 或 dll 时,您可以使用 lib/dll 将其更改为 /MD,这很容易。

于 2014-03-11T19:32:50.053 回答