[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. 高可用,完全分布式Hadoop集群HDFS和MapReduce安装配置指南

    原文:http://my.oschina.net/wstone/blog/365010#OSC_h3_13 (WJW)高可用,完全分布式Hadoop集群HDFS和MapReduce安装配置指南 [X] ...

  2. 转 jQuery中的$.extend方法来扩展JSON对象

    $.extend方法可以扩展JSON对象,用一个或多个其他对象来扩展一个对象,返回被扩展的对象. 例一 合并 settings 和 options,修改并返回 settings var setting ...

  3. nginx + uwsgi 部署 Django+Vue项目

    nginx + uwsgi 部署 Django+Vue项目 windows 本地 DNS 解析 文件路径 C:\Windows\System32\drivers\etc 单机本地测试运行方式,调用dj ...

  4. 如何学习Linux性能优化?

    如何学习Linux性能优化? 你是否也曾跟我一样,看了很多书.学了很多 Linux 性能工具,但在面对 Linux 性能问题时,还是束手无策?实际上,性能分析和优化始终是大多数软件工程师的一个痛点.但 ...

  5. eclipse中添加server后,启动server,访问项目时,端口是怎么选择的。

    1   eclipse中添加了tomcat 2 设置端口时,可以在图2.1修改 也可以在图2.2修改 3 点击server的publish按钮,会将图2.2的配置文件和server中添加的项目同步到实 ...

  6. python 中的__init__.py的用法与个人理解

    使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import 这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费 ...

  7. 009_python魔法函数

    11. (译)Python魔法方法指南 原文: http://www.rafekettler.com/magicmethods.html 原作者: Rafe Kettler 翻译: hit9 原版(英 ...

  8. hyperledge工具-cryptogen

    参考:http://baijiahao.baidu.com/s?id=1596614770784685300&wfr=spider&for=pc cryptogen是Hyperledg ...

  9. 在DreamView中支持一辆新车

    Support a new Vehicle in DreamView In order to support a new vehicle in DreamView, please follow the ...

  10. 从零开始搭建django前后端分离项目 系列一(技术选型)

    前言 最近公司要求基于公司的hadoop平台做一个关于电信移动网络的数据分析平台,整个项目需求大体分为四大功能模块:数据挖掘分析.报表数据查询.GIS地理化展示.任务监控管理.由于页面功能较复杂,所以 ...