2009-04-16 113 views
98

在Visual Studio中,有编译标志/ MD和/ MT,它们允许您选择所需的哪种C运行时库。我应该用/ MD还是/ MT编译?

我明白实施中的差异,但我仍不确定要使用哪一个。有什么优点/缺点?

我听说过的/ MD的一个优点是,它允许有人更新运行时(可能会修补安全问题),我的应用程序将从此更新中受益。虽然对我来说,这几乎看起来像一个非功能:我不希望人们更改我的运行时间,而不允许我测试新版本!

有些事情,我很好奇:

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

更多的信息和建议可以在:http:// stackoverflow。com/questions/787216 – Weidenrinde 2009-05-13 09:00:24

回答

66

通过与/ MD动态链接,

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

我还发现,在实践中,当处理与不同运行时选项构建的静态链接的第三方二进制只有库时,主应用程序中的/ MT会更频繁地导致冲突比/ MD(因为如果C运行时被多次静态链接,如果它们是不同的版本,你会遇到麻烦)。

+10

SxS会降低系统更新位数。该EXE得到宣布,它希望它的CRT版本(想要的,不是得到 - 安全更新可能否决这个) – MSalters 2009-04-17 13:49:40

+0

这是否意味着,如果我编译使用MD,我的计划是依赖于某些DLL,程序会如果它在计算机上运行失败依赖项DLL不存在的地方? – gerrytan 2013-10-03 05:09:03

14

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

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

我使用/ MT自己,以便我可以忽略整个DLL混乱。

P.S.正如Mr. Fooz指出的那样,保持一致至关重要。如果你与其他库链接,你需要使用他们所做的相同选项。如果您使用的是第三方DLL,几乎可以确定您需要使用运行时库的DLL版本。

4

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链接动态。

9

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

即使您使用/ MD获得较小的可执行文件,仍然必须发布一堆DLL以确保用户获得正确的版本以运行程序。最后你的安装程序会比使用/ MT连接时更大。

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

6

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

在这种情况下,你必须弄清楚如何在他们的机器上获得正确的版本。

26

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

如果您为.exe和所有.dll使用动态CRT,那么它们将共享一个CRT的实现 - 这意味着它们将共享一个CRT堆并将内存分配到一个.exe/.dll可以被释放在另一个。

如果您为.exe和所有.dll文件使用静态CRT,那么它们将全部获得CRT的单独副本 - 这意味着它们都将使用自己的CRT堆,因此内存必须在相同空间中释放分配给它的模块。你还会遇到代码膨胀(CRT的多个副本)和额外的运行时间开销(每个堆从操作系统分配内存来跟踪其状态,并且开销可能很明显)。

1

如果您正在构建使用其他dll或libs的可执行文件,而不是/ MD选项,那么所有组件都将共享相同的库。当然,这个选项应该适用于所有涉及的模块,即dll/lib/exe。

如果您的可执行文件不使用任何lib或dll比其他人的电话。现在差别不大,因为分享方面没有发挥作用。

所以,也许你可以用/ MT启动应用程序,因为除此之外没有任何强制性的理由,但是当它添加lib或dll的时候,你可以用lib/dll更改为/ MD,这很容易。