[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运行时库CRTVC6.0VC2005VC2008VC2010均提供了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.DLLMSVCP60.DLL的情况。

在这里介绍一个很好的工具:Dependency Walker,可以用来分析DLL的依赖关系,同时查看DLL导出的函数,使用方法请Google。

使用该工具打开MSVCRT.DLL,如下图:

我们可以在其中找到我们经常使用使用的C函数,如printf ,getcharmalloc等。

打开MSVCP100.DLL,也可以找到这些C函数

在开发的过程中我们也会遇到如下图的链接错误,LIBCD.lib究竟是何方神圣呢?

它其实是LIBC.lib的调试版,而LIBC.lib是只有在VC6.0才会使用的静态库,该库是CRT的单线程版,用于支持单线程版本的CRTVC2005等更高版本的编译器已经不再提供单线程版本,转而使用多线程版的MSVCR80.DLLlibcmt.lib
 
当遇到上述符号定义冲突的链接错误时,可以选择忽略libcd.lib

2014.2.28 于浙江杭州

[转帖]你所不知道的C和C++运行库的更多相关文章

  1. 你所不知道的C和C++运行库 标签: vc 2017-05-26 10:33 41人阅读 评论(0) 收藏

    在使用vs2013调用vc2005编译出的dll时出现错误,遂将源程序用vs2013编译出dll,再用vs2013调用错误消失,不解.寻找原因时有人说"VC库版本不一样",故查找C ...

  2. [转帖]QC 和 PD:关于你所不知道的快充

    QC 和 PD:关于你所不知道的快充 http://www.sohu.com/a/276214250_465976 2018-11-18 06:02 当我们使用支持 PD 或者 QC 快充协议的电源适 ...

  3. 你所不知道的setInterval

    在你所不知道的setTimeout记载了下setTimeout相关,此篇则整理了下setInterval:作为拥有广泛应用场景(定时器,轮播图,动画效果,自动滚动等等),而又充满各种不确定性的这set ...

  4. 你所不知道的setTimeout

    JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.它们向任务队列添加定时任务.初始接触它的人都觉得好简单 ...

  5. 你真的会玩SQL吗?你所不知道的 数据聚合

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  6. 你所不知道的linq(二)

    上一篇说了from in select的本质,具体参见你所不知道的linq.本篇说下from...in... from... in... select 首先上一段代码,猜猜结果是什么? class P ...

  7. 你所不知道的SQL Server数据库启动过程,以及启动不起来的各种问题的分析及解决技巧

    目前SQL Server数据库作为微软一款优秀的RDBMS,其本身启动的时候是很少出问题的,我们在平时用的时候,很少关注起启动过程,或者很少了解其底层运行过程,大部分的过程只关注其内部的表.存储过程. ...

  8. 你所不知道的SQL Server数据库启动过程(用户数据库加载过程的疑难杂症)

    前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的一些问题和解决方法,可点击查看,我们此篇主要介绍的是SQL Server启动过程中关于用户数据库加载的流程, ...

  9. Android中Context详解 ---- 你所不知道的Context

    转自:http://blog.csdn.net/qinjuning/article/details/7310620Android中Context详解 ---- 你所不知道的Context 大家好,  ...

随机推荐

  1. MYSQL基本操作(下)

    好了,废话不多说,接着开始Mysql剩下部分的小结了 Mysql 之 基础下 事务 事务:一系列将要发生或正在发生的连续操作,旨在保证数据操作的完整性.在事务开启之后,所有的操作都会被临时存储到事务日 ...

  2. Win7 下安装ubuntu14.04双系统

    下面介绍一下利用wubi在Windows中安装Ubuntu 14.04的教程,或者说安装方法和注意事项.  方法一:直接下载wubi.exe 方法二:直接下载ubuntu-14.04-desktop- ...

  3. ES5-ES6-ES7_iterator和for of

    iterator(遍历器)的概念 JavaScript原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6又添加了Map和Set.这样就有了四种数据集合,用户还可以组合 ...

  4. 直接运行vue+django项目

    直接运行vue+django项目 下载前后端代码 wget https://files.cnblogs.com/files/pyyu/luffy_boy.zip wget https://files. ...

  5. [HAOI2018]苹果树

    嘟嘟嘟 这种计数大题就留给南方的计数神仙们做吧-- 刚开始我一直想枚举点,考虑新加一个点在根节点的左右子树,以及左右子树大小怎么分配,但是这样太难计算新的点带来的贡献了. 后来lba又提示我枚举边,考 ...

  6. P1024 一元三次方程求解(二分答案)

    思路: 求这个根,然后有一个关键的条件|x1-x2|>=1,然后就是从-100,枚举到+100,每次二分(i, i+1)注意如果f(i)*f(i+1)>0则不进行二分,如果,你觉得这样的值 ...

  7. hash_hmac 签名

    <?php /** * =========================================================== * Model_Base * Descriptio ...

  8. python textwrap的使用

    参考:https://docs.python.org/3.6/library/textwrap.html textwrap模块提供了一些方便的函数,以及TextWrapper类,它执行所有的工作.如果 ...

  9. tomcat 启动慢问题

    主要原因: 生成随机数的时候卡住了,导致tomcat启动不了. 是否有足够的熵来用于产生随机数,可以通过如下命令来查看 [root@oldboy tools]# cat /proc/sys/kerne ...

  10. docker 15 dockerfile案例-CMD、ENTRYPOINT案例

    CMD.ENTRYPOINT都是指定一个容器启动时要运行的命令.但是CMD会覆盖前面的参数,而ENTRYP会追加组合原来的参数 未完待续...