新浪博客

/MD与/MT、/MTD与/MDD的区别

2018-05-19 13:11阅读:
/MD
使应用程序使用运行时库的多线程并特定于DLL 的版本。定义 _MT 和 _DLL,并使编译器将库名 MSVCRT.lib 放入 .obj文件中。
用此选项编译的应用程序静态链接到MSVCRT.lib。该库提供允许链接器解析外部引用的代码层。实际工作代码包含在 MSVCR90.DLL, 中,该库必须在运行时对于与MSVCRT.lib 链接的应用程序可用。
当/MD 与 _STATIC_CPPLIB 预处理器定义 (/D_STATIC_CPPLIB)一起使用时,您的应用程序将与静态多线程标准 C++ 库 (libcpmt.lib) 而非动态版本 (msvcprt.lib)链接,但仍通过 msvcrt.lib 动态链接到主 CRT。
请注意,不支持_STATIC_CPPLIB 预处理器定义和 /clr 或 /clr:pure 编译器选项的组合。有关 /clr选项的限制的更多信息,请参见 /clr 限制。
/MDd
定义_DEBUG、_MT 和 _DLL,并使应用程序使用运行时库的调试多线程并特定于 DLL 的版本。它还使编译器将库名MSVCRTD.lib 放入 .obj 文件中。
/MT
使应用程序使用运行时库的多线程静态版本。定义_MT 并使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用 LIBCMT.lib解析外部符号。
/MTd
定义_DEBUG 和 _MT。此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便链接器使用LIBCMTD.lib 解析外部符号。

/LD
创建DLL。
将/DLL 选项传递到链接器。链接器查找 DllMain 函数,但并不需要该函数。如果没有编写 DllMain 函数,链接器将插入返回TRUE 的 DllMain 函数。
链接DLL 启动代码。
如果命令行上未指定导出(.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL的应用程序。
将/Fe(命名 EXE 文件) 解释为命名 DLL 而不是 .exe 文件;默认程序名成为基名称.dll而不是基名称.exe。
除非显式指定/MD,否则将暗指 /MT。
/LDd
创建调试DLL。定义 _MT 和 _DEBUG。
看到这里,我恍然大悟,原来这个开关就是控制这个C运行时库的引用方式的,真是踏破铁鞋无觅处得来全不费工夫。
当然到这里先别忙着去修改你的项目属性中关于这个开关的选项,因为当你的项目也是一个LIB时,如果使用了/MT或/MTd选项时,最终的静态LIB中就会出现LIBCMT.lib中的大量符号,导致在别的项目引用你的这个静态LIB时出现重复定义符号而无法链接的错误,怎么解决呢?其实继续看MSDN中的帮助就可以得到答案:传递给链接器的给定调用的所有模块都必须使用相同的运行时库编译器选项(/MD、/MT、/LD)进行编译。
呵呵,原来如此,所有的模块保持一致就完了,但是静态的LIB貌似还是无法引用,问题依旧怎么办呢?那就是在引用了你自己的使用/MT或/MTd选项编译生成的静态LIB的项目中,不但指定对应的/MT或/MTd选项,而且需要忽略LIBCMT.lib库即可。
到这里这个很纠结的问题,总算是有一个非常完满的解决方法了。总结下来,其实也怪自己,《VC++语言参考手册》中其实早就描述过这个问题了,而我没有注意,导致为这个非常基础的问题纠结了这么长的时间,实在是汗颜。在这里也非常感谢那位总监高手,轻松的解决了这个问题。也为以后大家也不再为这个问题发愁,所以写成这篇文章,让大家作为参考。

我的更多文章

下载客户端阅读体验更佳

APP专享