[转帖]你所不知道的C和C++运行库
[C-C++]你所不知道的C和C++运行库
https://blog.csdn.net/humanking7/article/details/85887884 原作者也是转的blog 最近一个物理机上面的workstation 总是缺少一个dll 启动不起来 折腾了很久 突然想起来 我这边机器还经常缺少MSVCR100 之类的dll 今天晚上心血来潮 趁着孩子睡觉 翻一下blog 解决了之前一直迷惑的地方。 不同版本 不同依赖关系 需要的vc++ runtime 是不一样的。 不一定高版本一定 就没问题 低版本就不行的。 这一块 还是需要不停的学习与提高解决。
文章目录
原文:你所不知道的C和C++运行库
转载后只做了格式上的编辑,原文如下:
周五晚,小雨,少见的未加班。无聊,遂准备写一篇博客,介绍一下C和C++运行库,只因发现工作几年的人对此一知半解的大有人在。
在使用VC构建项目时,经常会遇到下面的链接错误:
初学者面对这些错误常常不知所错:libcmt.lib
是什么东西?msvcrtd.dll
又是干吗用的?在使用VC++
时我们也常常对下面的运行库配置项感到疑惑,它们到底究竟是什么意思呢?甚至一些工作了很多年的程序员也对此一知半解。今天让我们来了解一下它们。
从C和C++运行库说起
为了提高C语言的开发效率,C标准定义了一系列常用的函数,称为C库函数
。C标准仅仅定义了函数原型,并没有提供实现。因此这个任务留给了各个支持C语言标准的编译器
。每个编译器通常实现了标准C的超集
,称为C运行时库(C Run Time Libray)
,简称CRT
。对于VC++编译器
来说,它提供的CRT库支持C标准定义的标准C函数,同时也有一些专门针对windows系统特别设计的函数。
与C语言类似,C++也定义了自己的标准,同时提供相关支持库,我们把它称为C++运行时库
或C++标准库
。
由于C++对C的兼容性
,C++标准库
包括了C标准库
,除此之外还包括IO流
和标准模板库STL
。
VC++在何处实现C和C++运行库
VC++
完美的支持C和C++标准
,因此也就按照C和C++的标准定义的函数原型
实现了上述运行时库
。为了方便有不同需求的客户的使用,VC++
分别实现了动态链接库DLL版本
和静态库LIB版本
。同时为了支持程序调试且不影响程序的性能,又分别提供了对应的调试版本。调试版本的名称在Release版本
名称后添了字母d
。
对于C运行时库CRT
,VC6.0
、VC2005
、VC2008
和VC2010
均提供了DLL版本
和LIB版本
。上述各个编译器提供的LIB版的CRT库
,均实现在libcmt.lib
。对应的调试版名称为libcmtd.lib
。
而DLL版本名称根据编译器不同而不同,我们可以从名称上加以分辨:
VC6.0
使用的CRT库
的DLL版本在MSVCRT.DLL
中实现, 对应调试版本为MSVCRTD.LIB
。VC2005
使用的CRT库
的DLL版本在MSVCR80.DLL
中实现,对应调试版本为MSVCR80.DLL
。VC2008
使用的CRT库
的DLL版本在MSVCR90.DLL
中实现,对应调试版本为MSVCR90D.DLL
。VC2010
使用的CRT库
的DLL版本在MSVCR100.DLL
中实现,对应调试版本为MSVCR100D.DLL
。
C++标准兼容C标准
,但VC各版本
将C++编译器
使用的C标准库与C编译器
使用的C运行库
一起实现,它们使用相同的运行库
。
对于C++标准库
中的IO流
和STL,VC6.0、VC2005、VC2008和VC2010
也提供了DLL版本
和LIB版本
。
LIB版
均实现在libcpmt.lib
中,对应的调试版本为libcpmtd.lib
。
不同版本的编译器实现的DLL也不相同:
VC6.0
使用的C++类库
的 DLL版本在MSVCP60.DLL
中实现, 对应调试版本为MSVCP60D.LIB
。VC2005
使用的C++类库
的DLL版本在MSVCP80.DLL
中实现,对应调试版本为MSVCP80.DLL
。VC2008
使用的C++类库
的 DLL版本在MSVCP90.DLL
中实现,对应调试版本为MSVCP90D.DLL
。VC2010
使用的C++类库
的DLL版本在MSVCP100.DLL
中实现,对应调试版本为MSVCP100D.DLL
。
在各个版本的编译器中,我们可以通过配置选项来设置程序使用的C和C++运行时库
的类型。如下图(其他版本编译器大同小异):
MT选项
:链接LIB版的C和C++运行库
。在链接时就会在将C和C++运行时库
集成到程序中
成为程序中的代码
,程序体积会变大。MTd选项
:LIB的调试版
。MD选项
:使用DLL版的C和C++运行库
,这样在程序运行时会动态的加载对应的DLL
,程序体积会减小,缺点是在系统没有对应DLL时程序无法运行
。MDd选项
:表示使用DLL的调试版
。
在《由使用LeakDialog时遇到的问题而引出的一些分析》这篇文章中的实验一,使用VC6.0
的默认配置没有拦截到内存泄露。其原因是VC6.0
的控制台项目默认配置是静态链接CRT库
(单线程版,后面会介绍)。
动态版(DLL)和静态版(LIB)C和C++运行库的优缺点
因为静态版
必须把C和C++运行库
复制到目标程序
中,所以产生的可执行文件会比较大
。同时对于使用多个模块
的大型软件
来说,如果每个模块
均选择静态链接C或C++运行库
,在程序运行时就会存在多个运行库
。在链接时也会出现重复定义的问题
,如文章首第一张图所示。
使用DLL版的C和C++运行库
,程序在运行时动态的加载对应的DLL
。程序体积变小,但一个很大的问题就是一旦找不到对应DLL,程序将无法运行。假设使用VC6.0
并选择使用MD选项构建
,那么当用户使用VC2005
来使用这个DLL
时很可能出现找不到MSVCRT.DLL
或MSVCP60.DLL
的情况。
在这里介绍一个很好的工具:Dependency Walker
,可以用来分析DLL的依赖关系
,同时查看DLL导出的函数
,使用方法请Google。
使用该工具打开MSVCRT.DLL
,如下图:
我们可以在其中找到我们经常使用使用的C函数
,如printf
,getchar
,malloc
等。
打开MSVCP100.DLL
,也可以找到这些C函数
:
在开发的过程中我们也会遇到如下图的链接错误,LIBCD.lib
究竟是何方神圣呢?
它其实是LIBC.lib
的调试版,而LIBC.lib
是只有在VC6.0
才会使用的静态库,该库是CRT的单线程版
,用于支持单线程版本的CRT
。VC2005
等更高版本的编译器已经不再提供单线程版本,转而使用多线程版的MSVCR80.DLL
或libcmt.lib
。
当遇到上述符号定义冲突的链接错误时,可以选择忽略libcd.lib
。
2014.2.28 于浙江杭州
[转帖]你所不知道的C和C++运行库的更多相关文章
- 你所不知道的C和C++运行库 标签: vc 2017-05-26 10:33 41人阅读 评论(0) 收藏
在使用vs2013调用vc2005编译出的dll时出现错误,遂将源程序用vs2013编译出dll,再用vs2013调用错误消失,不解.寻找原因时有人说"VC库版本不一样",故查找C ...
- [转帖]QC 和 PD:关于你所不知道的快充
QC 和 PD:关于你所不知道的快充 http://www.sohu.com/a/276214250_465976 2018-11-18 06:02 当我们使用支持 PD 或者 QC 快充协议的电源适 ...
- 你所不知道的setInterval
在你所不知道的setTimeout记载了下setTimeout相关,此篇则整理了下setInterval:作为拥有广泛应用场景(定时器,轮播图,动画效果,自动滚动等等),而又充满各种不确定性的这set ...
- 你所不知道的setTimeout
JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务.初始接触它的人都觉得好简单 ...
- 你真的会玩SQL吗?你所不知道的 数据聚合
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你所不知道的linq(二)
上一篇说了from in select的本质,具体参见你所不知道的linq.本篇说下from...in... from... in... select 首先上一段代码,猜猜结果是什么? class P ...
- 你所不知道的SQL Server数据库启动过程,以及启动不起来的各种问题的分析及解决技巧
目前SQL Server数据库作为微软一款优秀的RDBMS,其本身启动的时候是很少出问题的,我们在平时用的时候,很少关注起启动过程,或者很少了解其底层运行过程,大部分的过程只关注其内部的表.存储过程. ...
- 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)
前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的一些问题和解决方法,可点击查看,我们此篇主要介绍的是SQL Server启动过程中关于用户数据库加载的流程, ...
- Android中Context详解 ---- 你所不知道的Context
转自:http://blog.csdn.net/qinjuning/article/details/7310620Android中Context详解 ---- 你所不知道的Context 大家好, ...
随机推荐
- echarts设置y轴值间隔
其中min.max可以自定义可以动态获取数据 yAxis : [ { type : 'value', axi ...
- nginx作为负载均衡服务器,tomcat作为应用服务器
1 如果想用一台主机,能够部署多个站点,并且访问每个站点都要求是在80端口,可以采用nginx+tomcat的方式 需要注意的是,tomcat一定不要监听80端口. 可以将静态资源配置在nginx ...
- 在asp.net web api中利用过滤器设置输出缓存
介绍 本文将介绍如何在asp.net web api中利用过滤器属性实现缓存. 实现过程 1,首先在web.config文件下appsettings下定义“CacheEnabled”和“CacheTi ...
- [HEOI2015]小Z的房间 && [CQOI2018]社交网络
今天看了一下矩阵树定理,然后学了一下\(O(n ^ 3)\)的方法求行列式. 哦对了,所有的证明我都没看-- 这位大佬讲的好呀: [学习笔记]高斯消元.行列式.Matrix-Tree 矩阵树定理 关于 ...
- java xml文件中相同Id遍历
import java.io.File;import java.util.List;import org.dom4j.Document;import org.dom4j.DocumentExcepti ...
- Python框架学习之Flask中的常用扩展包
Flask框架是一个扩展性非常强的框架,所以导致它有非常多的扩展包.这些扩展包的功能都很强大.本节主要汇总一些常用的扩展包. 一. Flask-Script pip install flask-scr ...
- hyperledge工具-cryptogen
参考:http://baijiahao.baidu.com/s?id=1596614770784685300&wfr=spider&for=pc cryptogen是Hyperledg ...
- Debian 8.9 搭建wordpress个人博客
想自己搭个博客玩玩,就搭建了此博客,过程可谓艰辛啊! 先在阿里云买了个 轻量应用服务器 1个月10块钱,好贵.... 用 windows sever 下载不了phpstudy,也不知道怎么回事... ...
- 理论篇-MySQL知识汇总
1. 唯一索引 普通索引允许被索引的数据列包含重复的值.唯一索引则是不允许有重复的值,当然 null 除外,唯一索引不仅仅可以存储 null , 还可以存储多个 null.这么做的好处是: 简化了My ...
- Wireshark抓包分析TCP 3次握手、4次挥手过程
Wireshark简介 更多有关Wireshark的教程.软件下载等,请见:http://www.52im.net/thread-259-1-1.html,本文只作简要介绍. 1Wireshark 是 ...