在Visual Studio中,有编译标志/ MD和/ MT,可让您选择所需的C运行时库类型.
我理解实现方面的差异,但我仍然不确定使用哪一个.有哪些优点/缺点?
我听说过/ MD的一个优点是,这允许有人更新运行时(比如修补安全问题),我的应用程序将从此更新中受益.虽然对我而言,这几乎看起来像一个非特征:我不希望人们改变我的运行时而不允许我测试新版本!
我很好奇的一些事情:
这会如何影响构建时间?(据推测/ MT有点慢?)
其他含义是什么?
大多数人使用哪一个?
Mr Fooz.. 80
通过动态链接/ MD,
你接触到系统更新(无论好坏),
您的可执行文件可以更小(因为它没有嵌入库中),以及
我相信至少DLL的代码段在所有正在使用它的进程之间共享(减少消耗的RAM总量).
我还发现,在实践中,当使用静态链接的第三方二进制库(使用不同的运行时选项构建)时,主应用程序中的/ MT往往比/ MD更常引起冲突(因为你如果C运行时多次静态链接会遇到麻烦,特别是如果它们是不同的版本).
通过动态链接/ MD,
你接触到系统更新(无论好坏),
您的可执行文件可以更小(因为它没有嵌入库中),以及
我相信至少DLL的代码段在所有正在使用它的进程之间共享(减少消耗的RAM总量).
我还发现,在实践中,当使用静态链接的第三方二进制库(使用不同的运行时选项构建)时,主应用程序中的/ MT往往比/ MD更常引起冲突(因为你如果C运行时多次静态链接会遇到麻烦,特别是如果它们是不同的版本).
如果您使用的是DLL,那么您应该选择动态链接的CRT(/ MD).
如果您为.exe和所有.dll使用动态CRT,那么它们将共享CRT的单个实现 - 这意味着它们将共享一个CRT堆,并且在一个.exe/.dll中分配的内存可以被释放另一个.
如果你为你的.exe和所有.dll使用静态CRT,那么他们都会获得CRT的单独副本 - 这意味着他们都将使用自己的CRT堆,因此必须在与其相同的模块中释放内存被分配了.您还会遇到代码膨胀(CRT的多个副本)和过多的运行时开销(每个堆从OS分配内存以跟踪其状态,并且开销可能很明显).
我相信通过Visual Studio构建的项目的默认值是/ MD.
如果使用/ MT,则可执行文件不依赖于目标系统上存在的DLL.如果你将它包装在一个安装程序中,它可能不是一个问题,你可以采取任何一种方式.
我自己使用/ MT,这样我就可以忽略整个DLL的混乱.
PS正如Fooz先生指出的那样,保持一致至关重要.如果您要与其他库链接,则需要使用与其相同的选项.如果您使用的是第三方DLL,则几乎可以肯定您需要使用运行时库的DLL版本.
我更喜欢静态链接/ MT.
即使您使用/ MD获得较小的可执行文件,您仍然需要发送一堆DLL以确保用户获得运行程序的正确版本.最后,与使用/ MT链接时,安装程序将变得更加庞大.
更糟糕的是,如果你选择将运行时库放在windows目录中,那么用户迟早会安装一个带有不同库的新应用程序,运气不好会破坏你的应用程序.
您将遇到/ MD的问题是CRT的目标版本可能不在您的用户计算机上(特别是如果您使用的是最新版本的Visual Studio且用户具有较旧的操作系统).
在这种情况下,你必须弄清楚如何在他们的机器上获得正确的版本.
来自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链接.