Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[C-C++]你所不知道的C和C++运行库

[C-C++]你所不知道的C和C++运行库

作者头像
祥知道
发布于 2020-03-10 08:38:11
发布于 2020-03-10 08:38:11
1.7K0
举报
文章被收录于专栏:祥的专栏祥的专栏
原创文章

文章目录
  • @[toc]
  • 从C和C++运行库说起
  • VC++在何处实现C和C++运行库
  • 动态版(DLL)和静态版(LIB)C和C++运行库的优缺点

原文:你所不知道的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函数,如printfgetcharmalloc等。

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
各个版本Microsoft Visual C++运行库下载
Microsoft Visual C++ 2005 Redistributable Package (x86) http://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.exe Microsoft Visual C++ 2005 Redistributable Package (x64) http://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.exe
全栈程序员站长
2022/09/09
3.9K0
Visual Studio中/MD /MDd /MT /MTd的含义以及_ITERATOR_DEBUG_LEVEL错误的解决方法
先上结论,如果你遇到了_ITERATOR_DEBUG_LEVEL doesnt match error,那一定是你链接的库的DEBUG或RELEASE版本与你当前的项目活动配置不符。不同的值代表的含义如下:
灰度五十
2022/03/08
1.9K0
lnk2001 lnk1120_lnk1120
学习VC++时经常会遇到链接错误LNK2001,该错误非常讨厌,因为对于编程者来说,最好改的错误莫过于编译错误,而一般说来发生连接错误时,编译都已通过。产生连接错误的原因非常多,尤其LNK2001错误,常常使人不明其所以然。如果不深入地学习和理解VC++,要想改正连接错误LNK2001非常困难。
全栈程序员站长
2022/11/08
1.1K0
浅谈 Qt 静态编译
本文要讲解的是Qt 静态编译,Qt中默认的应该是动态编译,那么本文就浅淡的介绍一下静态编译,先来看内容。
用户3519280
2023/07/06
1.2K0
常用运行库(VC++、DirectX)必备运行库
作用:提供多媒体(尤其是游戏)所需的图形、音频、输入 API 支持。 最新版本:DirectX 12(Windows 10/11 内置),但许多游戏仍依赖 DirectX 9.0c 组件。
西里网
2025/04/15
3.9K0
bjam 参数
注意,–build-type=complete表示生成debug release static shared的各种版本
用户3519280
2023/07/08
2580
如何在vs中链接vc6的运行时库
是这样,vc6的运行时库有个巨大的好处,就是全系列windows都自带了,而且不用管傻逼的manifest问题。
龙泉寺扫地僧
2019/02/20
1.8K0
运行时库
运行时库一般以dll形式存在,在程序启动的时候调用。如MFC的运行时库:MFC71.dll、MSVCR71.dll等。VS中可以通过配置环境变量是程序自动定位运行库的所在位置。
sofu456
2019/07/09
6710
运行时库
瓜哥教你上手就赢,VFP专属FLL开发入门
Visual FoxPro 动态连接库(FLL)实际上是包含对 VFP API 调用的DLL。可以使用C或者C++编写,目前MS VC系列开发工具,都是同时支持C和C++语法的,而FLL的接口只支持C语法,所以开发时接口部分需要遵循C约定,而具体实现代码则不分C或者C++,本文是写给希望使用VC开发VFP扩展库入门教程。
加菲猫的VFP
2022/04/07
1K0
瓜哥教你上手就赢,VFP专属FLL开发入门
微软VC运行库下载-Windows常用运行库完整版 V2023下载-Windows
安装这些运行库可以使得应用程序能够在Windows系统上正确运行,如果您发现某个应用程序无法正常运行,可能需要安装相应的运行库。可以从Microsoft官方网站或者第三方下载站点下载并安装这些运行库。
用户10519170
2023/04/21
1.6K0
c/c++ 软件集成 安装和可卸载软件
  作为一个工程师应具备的一些能力: 1. 首先具备这款软件:     >inno  Setup      免费版还开源,良心货,妥妥的。 2. 这款软件上手也比较款,可自行参考使用文档 3.编译成功,生成代码之后,样子可能如下: 1 ; Script generated by the Inno Setup Script Wizard. 2 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! 3
Gxjun
2018/03/26
1.2K0
c/c++ 软件集成 安装和可卸载软件
Visual C++ 微软常用运行库合集_2022.09.15
Microsoft Visual C++ Redistributable(简称MSVC,VB/VC,VC运行库)系统运行库是Windows操作系统应用程序的基础类型库的可再发行程序包.Microsoft Visual C++运行库是系统装机必备组件,此版VC++运行库合集(微软常用运行库合集),整合了所有版本Visual C ++,可以自选更新VC++版本组件,并提供图形安装界面.
星泽V社
2022/11/01
24.8K0
Visual C++ 微软常用运行库合集_2022.09.15
VC库的版本区分和对CPU算力的影响
HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64 HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\X64
Windows技术交流
2024/05/29
3790
[Setting]win7下运行exe失败:应用程序无法启动,因为应用程序的并行配置不正确
因为他们是新装的系统,给他们装的是Win7 32bit的系统,其它什么都没安装,根据网上的说明,估计是两个问题。
祥知道
2020/03/10
30.2K0
找不到MSVCR120.dll、VCRUNTIME140.dll、MSVCP140.dll
我做了个WinPE,在其中安装了https://www.falkon.org/ 浏览器,打开的时候报找不到MSVCR120.dll
Windows技术交流
2022/12/21
2.3K0
win7应用程序无法正常启动0xc0000142(0xc000007b解决方案)
我们新安装的windows10后,有一些应用程序活游戏无法正常启动,产生(0xc000007b)错误,产生的原因有以下三种可能:1、DirectX9没有安装2、MicrosoftVisualC++没有安装3、.net没有安装解决的方法有两种:第1种:安装VisualStudio2010(如果你需要编程的话)32位系统只安装32位的即可,64
Java架构师必看
2022/04/11
1.2K0
boost编译
经历了将近半年多的时间boost终于发布了1.35.0版本(前版本1.34.1发布于2007/7), 其编译方法和原来的编译方法基本上是一致的,主要改变包括1.34.0以来bjam的toolset所 提供的参数名称的改变(具体参见《boost1.34.0编译日志》)外,还包括bjam的编译默认 选项的变化,在1.35.0之前的版本默认编译时会自动编译各种版本的库,包括静态库、 动态库、debug库和release库等全部的版本,但是到了1.35.0时默认的选择仅仅编译release 版本的库,这样一来在开发的时候就不能进行必要的调试了,为了能够使其编译全部的版本 需要在bjam的命令行参数中添加一个–build-type=complete类型的参数来指明需要编译全 部的版本,所需要编译同时为了使得regex库能够通过ICU库支持Unicode,在编译上需要有 一些特殊的选择。我在Visual Studio 2005 Pro + SP1环境下编译了该库,为了避免走弯路 所以将其编译的方法进行说明,以方便大家编译。 由于boost是采用其自己的bjam工具通过命令行进行编译的,所以必须在Windows下开启console窗口,同时必须将Visual Studio中C++目录下的环境vcvarsall.bat配置脚本运行一遍,以设置好VC的编译器环境变量。 1. 编译不带ICU支持的boost库 此种情况下的boost库编译起来比较的简单,在准备好的console窗口中输入:
用户3519280
2023/07/08
3580
如何在各个版本的VC及64位下使用CPUID指令
 前面我们探讨了在16位的DOS实模式下使用CPUID指令(http://www.cnblogs.com/zyl910/archive/2012/05/14/dos16_getcpuid.html)。而现在64位Windows系统已经很流行了,在32/64位模式下如何使用CPUID呢?于是本文介绍了如何在各个版本的VC及64位下使用CPUID指令。
用户3519280
2023/07/06
9240
如何在各个版本的VC及64位下使用CPUID指令
系统上是否可以只共存多个版本visual c++可再发行包最新版的验证结果
最近在添加与删除程序中发现,系统中Microsoft Visual C++ Redistributable Package存在很多版本的,从2005、2008、2010都有,而且同一个发行版下还存在多个版本的。这都是安装visual studio(我只安装了visual studio 2012)、各类软件自带的发行包搞的。
williamwong
2018/07/24
3.1K0
系统上是否可以只共存多个版本visual c++可再发行包最新版的验证结果
从最小依赖角度谈静态库与动态库的选择及配置策略
在软件工程中,减少外部依赖不仅可以降低部署复杂度,还能提高系统的稳定性和安全性。本文将从“最小依赖”的角度出发,详细探讨在 C++ 项目中如何在静态库与动态库之间做出选择,并对常见的编译配置(如 /MT 与 /MD)的利弊进行分析。通过理论解析、代码示例与对比表格,帮助开发者在项目架构设计阶段作出更合理的决策。
码事漫谈
2025/02/24
2130
从最小依赖角度谈静态库与动态库的选择及配置策略
推荐阅读
相关推荐
各个版本Microsoft Visual C++运行库下载
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档