c运行库、c标准库、windows API的区别和联系( 二 )


}
从以上代码可知,运行库在调用用户程序的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的宽字符集版 。
Visual C++的运行时库源代码缺省情况下不被安装 。如果您想查看其源代码,则需要重装Visual C++,并在重装在时选中安装运行库源代码选项 。
 下面看一个未正确使用C运行时库的控制台程序:
#include
#include
int main()
{
 CFile file;
 CString str("I love you");
 TRY
 {
file.Open("file.dat",CFile::modeWrite | CFile::modeCreate);
 }
 CATCH( CFileException, e )
 {
#ifdef _DEBUG
afxDump << "File could not be opened " << e->m_cause << " ";
#endif
 }
 END_CATCH
 file.Write(str,str.GetLength());
 file.Close();
}
我们在"rebuild all"的时候发生了link错误:
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __endthreadex
nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol __beginthreadex
main.exe : fatal error LNK1120: 2 unresolved externals
Error executing cl.exe.
发生错误的原因在于Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程 。我们只需要在Visual C++6.0中依次点选Project->Settings->C/C++菜单和选项,在Project Options里修改编译选项即可 。
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标准库 。


推荐阅读