C运行库和C标准库的关系
C标准库,顾名思义既然是标准,就是由标准组织制定的。是由“美国国家标准协会(American National Standards Institute,ANSI)”为了规范C语言库而制定的标准。在最初,各个大学各个公司使用的C语言库都不尽相同,造成相互移植非常困难,在这个背景下,制定了这个标准。
C运行库,是和平台相关的,即和操作系统相关的。它由不同操作系统不同开发平台提供不同的C运行库。但是C运行库的部分实现是基于C标准库的,即C运行库是各个操作系统各个开发工具根据自身平台开发的库,某种程度上,可以说C运行库是C标准库的一个扩展库,只是加了很多C标准库所没有的与平台相关的或者不相关的库接口函数。举例子如:c标准库的strcpy函数负责字符串的拷贝,但是由于缺少对目地字符串缓冲区大小的控制,极有可能导致缓冲区溢出(大量的缓冲区溢出攻击都是由于这种漏洞而产生的);相反,Windows提供了能够实现同样功能的安全的字符串拷贝函数,减少了缓冲区攻击的可能,strcpy_s。这些函数是以c运行库的方式提供的,当然,不同的操作系统,c运行时库可能不同,但是对c标准库的支持是完全一致的,也就是说,在不同的操作系统上,使用同一个c标准库的函数必然产生一致的结果。
C标准库中提供的有:
l 标准输入输出(stdio.h)。
l 文件操作(stdio.h)。
l 字符操作(ctype.h)。
l 字符串操作(string.h)。
l 数学函数(math.h)。
l 资源管理(stdlib.h)。
l 格式转换(stdlib.h)。
l 时间/日期(time.h)。
l 断言(assert.h)。
l 各种类型上的常数(limits.h & float.h)。
你写的程序可以没有math库,程序照样运行,只是不能处理复杂的数学运算,不过如果没有了C run-time库,main()就不会被调用,exit()也不能被响应。因为C run-time library包含了C程序运行的最基本和最常用的函数。
如下是C运行库与C标准库的关系:
一个C运行库大致包含了如下功能:
l 启动与退出:包括入口函数及入口函数所依赖的其他函数等。
l 标准函数:由C语言标准规定的C语言标准库所拥有的函数实现。(C标准库)
l I/O:I/O功能的封装和实现,参见上一节中I/O初始化部分。
l 堆:堆的封装和实现,参见上一节中堆初始化部分。
l 语言实现:语言中一些特殊功能的实现。
l 调试:实现调试功能的代码。
操作系统API和C运行库CRT,C标准库之间
首先,C语言要早于Windows出现,而且C语言实际标准制定的开始时间也要早于Windows(API概念出现的)系统的开发时间。所以Windows系统在开发的时候是完全可以使用C语言的。目前最多的说法是用C和汇编实现的。那么只要用C,就可能用C标准库。
我们假设两种情况,一是Windows API的实现包含部分C标准库函数的功能实现,这就决定了这部分操作系统API的实现是由调用标准库实现的,那么在发布时需要加入所用到的c标准库DLL一同发布。
二是微软的内核(包括API)开发是使用着一个和平台严格相关的C语言的静态的链接库,这样不必提供Dll也能开发和发行。而且必然的这个C库是在汇编的基础上实现的,也就是说这个库里面的C函数都是(至少有很大比例)披着C语法的汇编代码。
要你是微软,你选择哪个呢?也许是两者兼而有之,也许是后者。
一般情况下,我们说C运行库暗含的意思是哪种平台哪个开发平台的C运行库,
CRT的实现是基于Windows API的,而WindowsAPI的开发也是基于C语言的,但不是或者不一定基于CRT(或者C标准库)的。
再深一步,虽然CRT是基于操作系统 API实现的,但并不代表所有的CRT封装了操作系统 API,如一些用户的权限控制,操作系统线程创建等都不属于C运行库,于是对于这些操作我们就不得不直接调用操作系统API或者其他库。
总结一下,C标准库就是任何平台都可以使用的基本C语言库。而CRT除了将C标准库加入所属范围外,还扩展了与平台相关的接口库,这些接口实现根据不同平台调用不同平台的操作系统API。
如下图所示,采用C标准库编写的程序可以应用到windows平台,也可以应用到linux平台;而用CRT另外与平台相关的库函数编写的应用程序不能跨平台运行。
而不同平台的操作系统API实现,是用C标准库呢,还是汇编呢,这个可有,可没有。毕竟那么多windows API只要发现一个调用C标准库的了,就有了。概念理解了即可,至于微软实现的时候基于何种考虑不使用C标准库,或者使用C标准库都有自己的考虑。那就是操作系统内部的研究范围了,等我知道了之后再确定这点。哈哈。。。。。。
理解不对的地方请大虾们多多指正。