在Visual Studio中,有编译标志/ MD和/ MT,可以让您选择所需的C运行时库。
我理解实现方面的差异,但我仍然不确定使用哪一个。有什么利弊?
我听说/ MD的一个优点是,这允许有人更新运行时(如可能修补安全问题),我的应用程序将从此更新中受益。虽然对我来说,这几乎看起来像一个非特征:我不希望人们改变我的运行时而不允许我测试新版本!
我很好奇的一些事情:
答案 0 :(得分:75)
通过动态链接/ MD,
我还发现,在实践中,当使用静态链接的第三方二进制库(使用不同的运行时选项构建)时,主应用程序中的/ MT往往比/ MD更容易引起冲突(因为如果C运行时多次静态链接会遇到麻烦,特别是如果它们是不同版本的话)。
答案 1 :(得分:29)
如果您使用的是DLL,那么您应该选择动态链接的CRT(/ MD)。
如果你为.exe和所有.dll使用动态CRT,那么它们将共享一个CRT的实现 - 这意味着它们将共享一个CRT堆和分配在一个.exe / .dll中的内存。被另一个人释放。
如果你为.exe和所有.dll使用静态CRT,那么他们都会获得CRT的单独副本 - 这意味着他们都将使用自己的CRT堆,因此必须在同一个模块中释放内存它被分配了。您还会遇到代码膨胀(CRT的多个副本)和过多的运行时开销(每个堆从操作系统分配内存以跟踪其状态,并且开销可能很明显)。
答案 2 :(得分:18)
我相信通过Visual Studio构建的项目的默认值是/ MD。
如果使用/ MT,则可执行文件不依赖于目标系统上存在的DLL。如果你将它包装在安装程序中,它可能不会成为问题,你可以采用任何一种方式。
我自己使用/ MT,这样我就可以忽略整个DLL的混乱。
P.S。正如Mr. Fooz指出的那样,保持一致至关重要。如果您要与其他库链接,则需要使用与其相同的选项。如果您使用的是第三方DLL,则几乎可以肯定您需要使用运行时库的DLL版本。
答案 3 :(得分:14)
我更喜欢静态链接/ MT。
即使您使用/ MD获得较小的可执行文件,仍然需要发送一堆DLL以确保用户获得运行程序的正确版本。最后,与使用/ MT链接时,安装程序将变得更加庞大。
更糟糕的是,如果您选择将运行时库放在Windows目录中,用户迟早会安装具有不同库的新应用程序,运气不好会破坏您的应用程序。
答案 4 :(得分:8)
您将遇到/ MD的问题是CRT的目标版本可能不在您的用户计算机上(特别是如果您使用的是最新版本的Visual Studio且用户具有较旧的操作系统)。
在这种情况下,你必须弄清楚如何在他们的机器上获得正确的版本。
答案 5 :(得分: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 会动态链接。
答案 6 :(得分:1)
如果您正在构建使用其他dll或libs的可执行文件而不是/ MD选项是首选,因为这样所有组件将共享相同的库。当然,这个选项应该与所有涉及的模块匹配,即dll / lib / exe。
如果您的可执行文件不使用任何lib或dll而不是任何人的电话。现在差别不是很大,因为共享方面没有发挥作用。
所以也许你可以用/ MT启动应用程序,因为没有令人信服的理由,但是当它添加lib或dll的时候,你可以用lib / dll的那个将它改成/ MD这很容易。< / p>