经常使用 Visual Studio 编译程序,经常被一些莫名其妙的错误搞懵,特别是提示链接库时候MT(d)或者MD(d)不对应,下面针对二者的区别简单介绍(带d的是对应的Debug版本)。
主要区别
首先看下二者的定义
/MD 表示多线程 DLL 版本,运行时库由 DLL 提供,即我们常说的动态链接态
/MT 表示多线程静态版本,程序不需要额外的 DLL,即我们常说的静态链接
同时,在编译器中针对不同的选择(包括 Debug 版本)提供了不同的定义,详细如下
选项 | 包含宏 | 链接库 |
---|---|---|
/MD | _MT _DLL | msvcrt.lib |
/MDd | _DEBUG _MT _DLL | msvcrtd.lib |
/MT | _MT | libcmt.lib |
/MTd | _DEBUG _MT | libcmtd.lib |
看到上面的库名称应该很熟悉了,经常在编译警告中见到。/MD
和 /MDd
版本的运行需要对应的 DLL,即 msvcr80.dll
以及 msvcr80d.dll
,数字代表了 Visual Studio 的版本,比如 Visual Studio 2010 是 10。
参考:https://docs.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=vs-2017
很多优秀的第三方库都提供了两种方式,比如boost,链接库的 /MT
版本文件名带 mt
字样。
编译选择
首先必须明确一点,就是不能同时链接这两种库,因为实现不一样,绝对不能混用。那么应该选哪个呢?
选择/MD的时候
可明显减少软件大小,毕竟很多动态库是共用的,也是现在推荐的方式
使用上,在内存申请上是相同的堆空间,不存在其他问题
选择/MT的时候
- 可以减少部署依赖缺失或版本不对应的问题
选/MT时候需要注意,各个运行库的堆空间不同,内存谁申请谁释放
其他说明
编译运行库选项的修改位置
Visual Studio 中修改上述选项的位置在,属性
- C/C++
- 代码生成
- 运行库
,注意 Debug 和 Release 不同配置。
其他运行库选项
上面的两个选项,都定义了 _MT
也就是说上述两个库都是多线程版本的,但其实还有个 /LD
的选项,暂且不论。
PS: 博客主题的表格样式终于弄好了,看着还行!