Runtime library, CRT
首先 ,看一句知乎的片段:https://www.zhihu.com/question/39858721/answer/83472146:
“Lampson也在图灵奖获奖演讲时曾说过一句话:Any problem in computer science can be solved with another level of indirection. (有人也说是David Wheeler说的)。 如由于计算机体系结构与资源是“赤裸丑陋”的,于是抽象出来一层操作系统进行计算机资源的管理与操作。而为了与操作系统交互,于是抽象出来了Runtime Library层,方式是System Call。而浏览器、编译器、Office等上层应用则仅需Runtime Library层交互即可,方式是Operating System API。” ----------- 正确性待考证!
--------- 以前,我只是接触到了application调用OS API.
application调用OS API, 例如,调用createThread函数,从此图来看,这个函数是以Runtime Library的形式提供服务的。
结合下面的文章整理一下这篇好文:https://blog.csdn.net/mvtechnology/article/details/72674042
https://blog.csdn.net/luoweifu/article/details/49055933 ------ 作者的知识很丰富!!::
什么是Runtime Library?
微软官方解释: https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=vs-2019
Runtime Library就是运行时库,也简称CRT(C Run Time Library)。是程序在运行时所需要的库文件,通常运行时库是以Lib或Dll形式提供的。
Windows下C Runtime Library是微软对C标准库函数的实现,这样每个程序可以直接使用C标准库的函数;后来出现了C++,于是又在C Runtime Library基础上开发了C++ Runtime Library,实现了对C++标准库的支持。因此现在Windows下的C/C++运行时库既包含子C标准库,也包含了C++标准库。
如果你安装了VS2010,在安装目录下的VC\crt\src下(如C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src)有运行时库(CRT)的源代码,这里既有C的文件(如output.c、stdio.h等),也有C++的文件(如iostream、string)。---- 每种编译器都自带这些库吗。
在C Runtime Library出现之前,许多程序都使用C编写,而这些程序都要使用标准的C库,按照以前的方式每一个程序最终都要拷贝一份标准库的实现到程序中,这样同一时刻内存中可能有许多份标准库的代码(一个程序一份),所以微软出于效率的考虑把标准C库做为动态链接来实现,这样多个程序使用C标准库时内存中就只有一份拷贝了。
确切地说运行时库指的就是对这些底层的基础功能实现的动态库(Dll),运行时库和普通的Dll一样,只有程序用到了它才会被加载,没有程序使用的时候不会驻留内存的。(底层功能的库才叫运行时库么)。话虽如此,但有多少系统的东西说不定也是用C写的,这些东西的存在就使C运行时库存在于内存中了,所以运行时库几乎总是需要的。虽然说运行时库应该是动态库,但习惯上我们把与动态运行时库相同代码编译出来的静态库也称为运行时库,VC++下的运行时库有ML、MLd、MT、MTd、MD、MD六种。
运行时库的主要作用:
- 提供C标准库(如memcpy、printf、malloc等)、C++标准库(STL)的支持。
- 应用程序添加启动函数,启动函数的主要功能为将要进行的程序初始化,对全局变量进行赋初值,加载用户程序的入口函数。
不采用宽字符集的控制台程序的入口点为mainCRTStartup(void)。下面我们以该函数为例来分析运行时库究竟为我们添加了怎样的入口程序。这个函数在crt0.c中被定义,下列的代码经过了笔者的整理和简化:
void mainCRTStartup(void)
{int mainret;/*获得WIN32完整的版本信息*/_osver = GetVersion();_winminor = (_osver >> 8) & 0x00FF ;_winmajor = _osver & 0x00FF ;_winver = (_winmajor << 8) + _winminor;_osver = (_osver >> 16) & 0x00FFFF ;_ioinit(); /* initialize lowio *//* 获得命令行信息 */_acmdln = (char *) GetCommandLineA();/* 获得环境信息 */_aenvptr = (char *) __crtGetEnvironmentStringsA();_setargv(); /* 设置命令行参数 */_setenvp(); /* 设置环境参数 */_cinit(); /* C数据初始化:全局变量初始化,就在这里!*/__initenv = _environ;mainret = main( __argc, __argv, _environ ); /*调用main函数*/exit( mainret );
}
从以上代码可知,运行库在调用用户程序的main或WinMain函数之前,进行了一些初始化工作。初始化完成后,接着才调用了我们编写的main或WinMain函数。只有这样,我们的C语言运行时库和应用程序才能正常地工作起来。
除了crt0.c外,C运行时库中还包含wcrt0.c、 wincrt0.c、wwincrt0.c三个文件用来提供初始化函数。wcrt0.c是crt0.c的宽字符集版,wincrt0.c中包含 windows应用程序的入口函数,而wwincrt0.c则是wincrt0.c的宽字符集版。
历史发展的角度讲解运行时库
1 从操作系统的角度出发
操作系统一般是用C写的(因为那时还没有C++,C已经算是最高级的计算机语言了),不管是Linux/Unix还是Windows底层都是大量的C代码。
在开发操作系统及相应的应用程序时,很多的程序都会用到相同基础功能的函数库。为了方便开发就把经常用到的底层的基础函数封闭成库(不然你每写一个程序都要把这基础功能实现的源代码拷贝一份到自己的工程,或自己再实现一次),于是就有了C运行时库(C Runtime Library),也就是静态库libc.lib(Release版)、libcd.lib(Debug版)。
因为早期的操作系统和程序都相应简单,用户的需求也不高,那时的操作系统还没有多任务、多线程的概念。所以libc.lib、libcd.lib当然只能支持单线程的程序,而无法支持多线程的程序,因此这个运行时库叫Single-Threaded。
后来,随着计算机的普及和发展,计算机要完成的任务越来越多,人们对时间和性能的要求也越来越高,为满足这些需求,操作系统就有了多任务的概念,也有了多线程的技术。而之前的运行时库libc.lib、libcd.lib只能用于单线程,已经无法满足很多程序的需要,于是多线程的运行时库也就应运而生,这就是libcmt.lib、libcmtd.lib。 这解决了多线程的问题,但随着程序的越来越复杂,一个程序可能会用到多个其他程序的库,多个程序可能会用到相同的库,导致多线程同时运行时,在内存中会保存多份的相同的静态库。假设A程序使用了C.lib,B程序也使用了C.lib,A、B程序同时运行时,在内存中就会同时存在两份C.lib。
静态库在内存中的呈现方式
为了解决这个问题,就产生了动态库的技术。于是就有了动态的运行时库Multi-threaded DLL、Multi-threaded DLL Debug。多个程序使用同一个动态库,在内存中只会有一份,效果图如下:
2 从语言的角度
我们都知道,先有了C语言,后来才在C的基础上发展出了C++语言,而C++又对C兼容,相当是C的一个超集。
一开始的运行时库,只是C的运行时库(C Runtime Library),包含了对C标准函数的实现。后来随着C++的产生,又把C++程序运行时要用的底层基础库加了进去,就有了C/C++的运行时库(C/C++ Runtime Library),这时的运行时库既包含了标准C函数的实现,也包含了C++ STL的实现。
在VS中设置运行时库的类型:
可以在Properties->Configuration Properties->C/C++->Code Generation->Runtime Library中设置采用的运行时库的类型。
我们知道编译出的静态库只有一个ProjectName.lib文件,而编译出的动态库有两个文件:ProjectName.lib+ProjectName.dll,一个是导入库,一个动态库。
VC++中有六种Runtime Library的类型:
你可以在VS的安装目录下找到这些库文件,如C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\ 和 C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64\中分别找到对应32位和64位的libcmt.lib、libcmtd.lib、msvcrt.lib、msvcrtd.lib库。
对于dll, 通过上面的表格你会发现,多线程的动态运行时库是 msvcrt.lib + msvcrtxx.dll,之所以是msvcrtxx.dll是因为每一个版本的VS使用的库名称还不一样。而且还不止包含一个库,除了主要的MSVCRT库外,还有MSVCPRT、MSVCIRT库。它们之间的对应关系如下:
在你的VS安装目录下(如C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\redist\x64\Microsoft.VC100.CRT),及系统目录C:\Windows\System32、C:\Windows\SysWOW64下都能找到对应的.dll库。
很多的软件在发布自己的产品时也都会带上这些DLL(防止用户的操作系统没有安装VS,或在系统目录下找不到对应的DLL(windows系统会没有这些文件么?)),如我电脑上的百度影音安装目录下就有MSVCR71.DLL(C:\Program Files (x86)\baidu\BaiduPlayer\4.1.2.286\MSVCR71.DLL),WPS的安装目录下有msvcr100.dll(C:\Program Files (x86)\WPS Office\9.1.0.5132\wtoolex\msvcr100.dll)和msvcp100.dll(C:\Program Files (x86)\WPS Office\9.1.0.5132\wtoolex\msvcp100.dll)。
(1). 静态链接的单线程库
静态链接的单线程库只能用于单线程的应用程序, C 运行时库的目标代码最终被编译在应用程序的二进制文件中。通过 /ML 编译选项可以设置 Visual C++ 使用静态链接的单线程库。
(2). 静态链接的多线程库
静态链接的多线程库的目标代码也最终被编译在应用程序的二进制文件中,但是它可以在多线程程序中使用。通过 /MT 编译选项可以设置 Visual C++ 使用静态链接的多线程库。
该选项生成的可执行文件运行时不需要运行时库dll的参加,会获得轻微的性能提升,但最终生成的二进制代码因链入庞大的运行时库实现而变得非常臃肿。当某项目以静态链接库的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份,最终将导致致命的“Invalid Address specified to RtlValidateHeap”问题。
(3). 动态链接的运行时库
动态链接的运行时库将所有的 C 库函数保存在一个单独的动态链接库 MSVCRTxx.DLL 中, MSVCRTxx.DLL 处理了多线程问题。使用 /MD 编译选项可以设置 Visual C++ 使用动态。
链接时将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接,在运行时要求安装了相应版本的VC运行时库可再发行组件包(当然把这些运行时库dll放在应用程序目录下也是可以的)。 因/MD和/MDd方式不会将运行时库链接到可执行文件内部,可有效减少可执行文件尺寸。当多项目以MD方式运作时,其内部会采用同一个堆,内存管理将被简化,跨模块内存管理问题也能得到缓解。
/MDd 、 /MLd 或 /MTd 选项使用 Debug runtime library( 调试版本的运行时刻函数库 ) ,与 /MD 、 /ML 或 /MT 分别对应。 Debug 版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,加强了对错误的检测,因此在运行性能方面比不上 Release 版本。
/MD和/MDd将是潮流所趋,/ML和/MLd方式请及时放弃,/MT和/MTd在非必要时最好也不要采用了。
在Windows下进行C++的开发,VS下的一项设置MT、MTd、MD和MDd却经常让人搞迷糊,特别是你工程使用了很多第三库的时候,及容易出现各种链接问题。看一下下面这个错误提示:
LIBCMT.lib(_file.obj) : error LNK2005: ___initstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: ___endstdio already defined in libc.lib(_file.obj)
REF:
https://blog.csdn.net/mvtechnology/article/details/72674042
https://blog.csdn.net/u012372584/article/details/78949261
Runtime library, CRT相关推荐
- CRT(C Runtime Library)—— C/C++运行时库
C runtime library(part of the C standard library) 任何一个 C 程序,它的背后都有一套庞大的代码来进行支撑,使得该程序得以运行在更高级别上,而不必担心 ...
- CRT (C run-time library)简介
来自 https://mp.weixin.qq.com/s/qg1mFzMEYv7GDDM72H1DOQ 操作系统学习 1. 什么是CRT crt是C run-time library的简称,称为C ...
- Glibc辅助运行库 (C RunTime Library): crt0.o,crt1.o,crti.o crtn.o,crtbegin.o crtend.o
crt1.o, crti.o, crtbegin.o, crtend.o, crtn.o 等目标文件和daemon.o(由我们自己的C程序文件产生)链接成一个执行文件.前面这5个目标文件的作用分别是启 ...
- C Runtime Library 的来历
由于我看到的文章也是转载的且未提供原文链接,所以这里没有提供原文链接,深表抱歉! msvcrt.dll (名称:Microsoft C Runtime Library)提供了printf,malloc ...
- Microsoft Visual C++ Runtime Library Runtime Error的解决的方法
打开浏览器时,出现Microsoft Visual C++ Runtime Library Runtime Error错误,初步预计是软件冲突,可能有多种出错的方式,我的是浏览器自己主动关闭. 一. ...
- Microsoft Visual C++ Runtime Library 错误解决办法
今天安装软件时,出现"Microsoft Visual C++ Runtime Library"错误,网上查了下解决方法,得以解决. 现在分享下,给碰到相同问题的朋友. 微软官方解 ...
- VC++六种Runtime Library
2019独角兽企业重金招聘Python工程师标准>>> VC++中有六种Runtime Library的类型: 类型 简称 含义 对应的库名称 备注 Single-Threaded ...
- C Runtime Library来历, API, MFC, ATL关系
首先说明,我google了半天,想找到英文的关于这个资料,但是实在找不到,只好转载国人的讨论. CRT原先是指Microsoft开发的C Runtime Library,用于操作系统的开发及运行.后来 ...
- 带你玩转Visual Studio(八)——带你跳出坑爹的Runtime Library坑
在Windows下进行C++的开发,不可避免的要与Windows的底层库进行交互,然而VS下的一项设置MT.MTd.MD和MDd却经常让人搞迷糊,相信不少人都被他坑过,特别是你工程使用了很多第三库的时 ...
- C Runtime Library 与 STL
C Runtime Library 的来历 msvcrt.dll (名称:Microsoft C Runtime Library)提供了printf,malloc,strcpy等C语言库函数,并且为使 ...
最新文章
- 牛客网 【每日一题】5月11日题目精讲 Moovie Mooving
- 域控下发脚本_域环境下做到单用户登陆控制脚本
- linux bash环境,Win10系统怎样启用Linux Bash环境
- java 线程 函数_java – 从后台线程调用主线程上的函数
- 4-7:TCP协议之流量控制
- 怎么查看过程xact_abort 是否开启_空调噪音大怎么办?
- mysql i o error_警告:mysqli_ERROR()需要精确的一个参数,0给定的错误
- Sun公司开源游戏服务器Project Darkstar Server——(Sun game server , 简称 sgs)学习笔记(二):多人游戏...
- linux下挂载U盘的方法
- [DesignPattern]各自用一句话来概括MVC、MVP、MVVM的差异特点
- python画满天星_跟我学解Python题-海龟制图满天星
- 15.正则表达式扩展正则字符处理
- 磁盘 IO 真的比网络 IO 快吗?
- 关于轩微电子ADS1256+stm32f103开发板的一点使用小tip
- Android低版本程序升级方法,安卓版本太低又无法升级,部分软件运行不了?
- 外贸邮箱用哪个邮箱号比较好,是多少?
- win10x64 批处理自动安装打印机
- ant-design中取消tab激活时候的下划线、以及修改tab激活时候下划线颜色
- 用手机APP的方式实现PLC远程监控
- 数据分析之Part1:商业数据分析入门