在开发window程序是经常会遇到编译好好的程序拿到另一台机器上面无法运行的情况,这一般是由于另一台机器上面没有安装相应的运行时库导致的,那么这个与编译选项MT、MTd、MD、MDd有什么关系呢?这是msdn上面的解释:

MT:mutithread,多线程库,编译器会从运行时库里面选择多线程静态连接库来解释程序中的代码,即连接LIBCMT.lib库

MTd:mutithread+debug,多线程调试版,连接LIBMITD.lib库

MD:MT+DLL,多线程动态库,连接MSVCRT.lib库,这是个导入库,对应动态库为MSVCRT.dll

MDd: MT+DLL+debug,多线程动态调试库,连接MSVCRTD.lib库,对应动态库为MSVCRTD.dll

开发多线程程序时(单线程本文不做讨论),需要选择MT、MTd、MD、MDd其中的一个。

对于MT/MTd,由于连接运行时库是LIBCMT.lib/LIBCMTD.lib,这两个库是静态库,所以此种方式编译的程序,移到另一台机器上面也可以正常运行,此方式性能上略有优势。

但是对于MD/MDd,连接的是动态库,所以如果另一台机器上没有MSVCRT.dll/MSVCRTD.dll时,就提示缺少动态库这样的错误。

曾经犯这样的错误,以为以MT/MTd方式编译,程序对所有的库都是静态链接的,其实错了,它只能决定运行时库是动态链接还是静态链接,对用户自己写的库或其他第三方库,其连接方式取决于代码(显式连接动态库Loadlibrary)或所提供的lib文件(为导入库还是静态库),移动程序到别的机器上时,还是要带上所需要的动态库的。

来看一个例子,编译一个静态库和一个动态库,均实现两个整数相加的功能:

// adds.h
// add后面加个s代表静态库
#pragma once
int add(int,int);
// adds.cpp
// 静态库
#include "adds.h"
int add(int a, int b)
{return a+b;
}

以上,运行时库选择MTd,编译成静态库adds.lib

// addd.h
// add后面加d代表动态库
#pragma once
#ifndef MYLIB_API
#define MYLIB_API _declspec(dllexport)
#endifMYLIB_API int  add(int,int);
// addd.cpp
// 动态库
#include "addd.h"
int add(int a, int b)
{return a+b;
}

以上,运行时库选择MTd,编译成动态库addd.lib, addd.dll

// test.cpp
// 测试程序
#include <iostream>// 测试静态库,此处为1,测试动态库,此处为0
#define TEST_STATIC_LINK 1#if TEST_STATIC_LINK #include <adds.h>
#else#define MYLIB_API _declspec(dllimport)#include "addd.h"
#endifusing namespace std;int main()
{cout << add(2,3) << endl;return 0;
}

测试程序以MTd编译
1. 测试静态库,TEST_STATIC_LINK 定义为1,提供adds.lib,生成可执行文件,移动到另一台机器上可以运行,因为测试程序和adds.lib均静态连接运行时库

2. 测试动态库,TEST_STATIC_LINK 定义为0,提供addd.lib,生成可执行文件,移动到另一台机器上可以运行,但需要addd.dll,因为addd库静态连接运行时库,测试程序静态连接运行时库,动态连接addd库

在上面的例子中add库和测试程序均选择MTd运行时库,若不一致会导致一些编译连接错误,让新手不着头脑。

比如adds选择MDd,连接将会出现这样的错误:

1>正在链接...

1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) 已经在LIBCMTD.lib(typinfo.obj) 中定义

1>MSVCRTD.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) 已经在LIBCMTD.lib(typinfo.obj) 中定义

即一个程序中混合了不同的运行时库(静态库和动态库,调试库和非调试库),可能会产生冲突,所以一个程序中应该使用相同的运行时库。

引用资料:

http://msdn.microsoft.com/en-us/library/2kzt1wy3(v=vs.71).aspx

visual studio运行时库MT、MTd、MD、MDd相关推荐

  1. visual studio运行时库MT、MTd、MD、MDd 的区别

    msdn上面的解释: MT:mutithread,多线程库,编译器会从运行时库里面选择多线程静态连接库来解释程序中的代码,即连接LIBCMT.lib库 MTd:mutithread+debug,多线程 ...

  2. vs编译c语言停止工作运行库mt,vc++编译时运行库选择(/MT/MTd/MD/MDd)

    vc++编译时运行库选择(/MT/MTd/MD/MDd) vc++编译时运行库选择(/MT./MTd./MD./MDd) 在vs中,项目属性 ->C/C++ ->代码生成 ->运行库 ...

  3. VC编译选项 /ML /MLd /MT /MTd /MD /MDd之间的区别

    VC编译选项 /ML /MLd /MT /MTd /MD /MDd之间的区别 VC编译选项 多线程(/MT) 多线程调试(/MTd) 多线程 DLL (/MD) 多线程调试 DLL (/MDd) C ...

  4. CMake设置MSVC工程MT/MTd/MD/MDd

    文章目录 0. 前言 1. 如何设置 1.1 CMakeLists代码 1.2 要点1:POLICY 1.3 要点2:set_property 0. 前言 在MSVC工程上右键->属性,找到配置 ...

  5. 什么是c/c++运行时库

    什么是c/c++运行时库 在各个版本的编译器中,我们可以通过配置选项来设置程序使用的C和C++运行时库的类型.如下图(其他版本编译器大同小异): MT选项:链接LIB版的C和C++运行库.在链接时就会 ...

  6. C++堆被破坏 运行时库

    每个进程都有一个默认堆,在进程初始化的时候会创建这个默认堆,可以通过GetProcessHeap()获取默认堆的句柄.使用CRT时,也会有一个CRT堆,VS项目属性 ~ C/C++ ~ 代码生成 ~ ...

  7. crt 运行时库dll跨模块传递crt对象,出现的崩溃问题

    参考链接: https://blog.csdn.net/weixin_30653097/article/details/96512399 (讲述了,运行时库在启动的时候在exe或dll入口点之前就使用 ...

  8. 如何在VS2005下生成动态运行时库

    如果我们的工程采用的是动态链接MFC库,那我们的程序如果拷贝到一个没有转VC的电脑中,我们的程序要想正确运行,除了拷贝程序外,还要将运行时库拷贝过去,下面记录下如何创建动态运行时库: file-> ...

  9. 【C 语言】动态库封装与设计 ( Windows 动态库简介 | Visual Studio 调用动态库 )

    文章目录 一.Windows 动态库简介 二.Visual Studio 调用动态库 一.Windows 动态库简介 在 C:\Windows\System32 目录中 , 存放着 Windows 中 ...

  10. Visual Studio使用opencv库

    1.准备好与vs版本对应的OpenCV,下载网址:https://opencv.org/release/ 2.opencv 配置环境变量 ①. 在环境变量中添加:OPENCV_DIR,它的值指向Ope ...

最新文章

  1. 定制适合自己的精简桌面环境
  2. 什么是分布式锁?redis、zookeeper、etcd实现分布式锁有什么不同之处?
  3. dvd管理器java_Java DVD管理器 基础示例代码下载
  4. SQL中显示查询结果的前几条记录
  5. 【渝粤题库】国家开放大学2021春2321物流学概论题目
  6. 程序员面试金典 - 面试题 01.02. 判定是否互为字符重排(哈希map)
  7. android给数组添加新元素_「数组赋值」什么是数组、如何创建数组、数组赋值、数组增加一个新元素 - seo实验室...
  8. 分治之快速排序以及快速排序为何最快
  9. 无向图中两点之间的距离_九上数学:二次函数图像,一动点到两定点距离和最小...
  10. 每天30分钟搞Software Rendering--(0)搜集资料,阅读,了解
  11. WORD中使用类似苹果手机的字体Lucida Sans
  12. 转:Scrapy(爬虫框架)入门教程
  13. STM32之提升迷之自信(时钟的制作)
  14. 关于EF Core中同一个实体被多次tracked的问题
  15. 浅析TVS管的响应时间与TVS管伏安特性曲线
  16. 查看centos是多少位的方式
  17. 聚焦时代起点 智启云上未来——IMPACT2018紫光云峰会在津举办
  18. 这是您正在找的大数据、人工智能实战培训课程!
  19. 光盘都无法识别解决方法
  20. Android P SystemUI之StatusBar UI布局status_bar.xml解析

热门文章

  1. SQL Server常用查询指令
  2. C语言学生管理程序输入错误,c语言编程,关于学生管理的程序(急急急)
  3. 梯度下降的线性回归用python_学习笔记:使用python 实现线性回归里的梯度下降...
  4. ssm连接mysql引入外部配置文件username无法被正确解析
  5. java背包算法_背包算法java版
  6. oracle临时表空间占用率过高,ORACLE临时表空间太大,如何处理?
  7. 关于jenkins打包部署
  8. CodeForce 855B 暴力or线段树
  9. java 8 接口默认方法
  10. 如何用Python脚本从文件读取数据?