1.C运行库和C语言函数库(象stdio.h,stdlib.h等)是不是同一个东西?
2.在技术参考书中老说“Microsoft C运行库”,那C运行库到底是语言本身的库还是操作系统的库?其它操作系统如unix/linux中有没有C运行库?
3.为什么既用Win32 API,还要用C运行库?前者能替代后者吗?
4.tchar.h、wchar.h是C运行库的头文件还是API的头文件?TCHAR、WCHAR类型及_TEXT、TEXT等宏分别在哪个里面定义的?
转贴) 1)运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 2)C 语言是所谓的“小内核”语言,就其语言本身来说很小(不多的关键字,程序流程控制,数据类型等);所以,C 语言内核开发出来之后,Dennis Ritchie 和 Brian Kernighan 就用 C 本身重写了 90% 以上的 UNIX 系统函数,并且把其中最常用的部分独立出来,形成头文件和对应的 LIBRARY,C run-time library 就是这样形成的。 3)随后,随着 C 语言的流行,各个 C 编译器的生产商/个体/团体都遵循老的传统,在不同平台上都有相对应的 Standard Library,但大部分实现都是与各个平台有关的。由于各个 C 编译器对 C 的支持和理解有很多分歧和微妙的差别,所以就有了 ANSI C;ANSI C (主观意图上)详细的规定了 C 语言各个要素的具体含义和编译器实现要求,引进了新的函数声明方式,同时订立了 Standard Library 的标准形式。所以C运行时库由编译器生产商提供。至于由其他厂商/个人/团体提供的头文件和库函数,应当称为第三方 C 运行库(Third party C run-time libraries)。 4)C run-time library里面含有初始化代码,还有错误处理代码(例如divide by zero处理)。你写的程序可以没有math库,程序照样运行,只是不能处理复杂的数学运算,不过如果没有了C run-time库,main()就不会被调用,exit()也不能被响应。因为C run-time library包含了C程序运行的最基本和最常用的函数。 5)到了 C++ 世界里,有另外一个概念:Standard C++ Library,它包括了上面所说的 C run-time library 和 STL。包含 C run-time library 的原因很明显,C++ 是 C 的超集,没有理由再重新来一个 C++ run-time library. VC针对C++ 加入的Standard C++ Library主要包括:LIBCP.LIB, LIBCPMT.LIB和 MSVCPRT.LIB 6)Windows环境下,VC提供的 C run-time library又分为动态运行时库和静态运行时库。 动态运行时库主要是DLL库文件msvcrt.dll(or MSVCRTD.DLL for debug build),对应的Import library文件是MSVCRT.LIB(MSVCRTD.LIB for debug build) 静态运行时库(release版)对应的主要文件是: LIBC.LIB (Single thread static library, retail version) LIBCMT.LIB (Multithread static library, retail version) msvcrt.dll提供几千个C函数,即使是像printf这么低级的函数都在msvcrt.dll里。其实你的程序运行时,很大一部分时间时在这些运行库里运行。在你的程序(release版)被编译时,VC会根据你的编译选项(单线程、多线程或DLL)自动将相应的运行时库文件(libc.lib,libcmt.lib或Import library msvcrt.lib)链接进来。 编译时到底哪个C run-time library联入你的程序取决于编译选项: /MD, /ML, /MT, /LD (Use Run-Time Library) 你可以VC中通过以下方法设置选择哪个C run-time library联入你的程序: To find these options in the development environment, click Settings on the Project menu. Then click the C/C++ tab, and click Code Generation in the Category box. See the Use Run-Time Library drop-down box. 从程序可移植性考虑,如果两函数都可完成一种功能,选运行时库函数好,因为各个 C 编译器的生产商对标准C Run-time library提供了统一的支持. 对该文的评论 han012 ( 2001-09-03) 很高兴有许多网友参与讨论,并对本文提出不同的观点, 在此表示感谢. 另外针对一些网友的评论,我想有必要进行一些补充: 1)在Windows环境中,直到VC++4.0之前(如果我没有记错)只有静态的C run-time library,之后才有了动态的C run-time library. 动态的C run-time library是以DLL形式给出的. 从理论上说,不论是静态的还是动态的C run-time library都是一些编译好的,可以被运行的二进制代码. 所以从理论上说,只要符合调用规则,"同一操作系统平台上的不同编译系统应该可以共享库文件"。在这一点上我也赞同PingPingPangPang. 正如在本文中没有一处说 "C run-time library"只能被C/C++使用." 2)虽然从理论上说,C run-time library可以被其他编译系统共享,但不得不承认C run-time library还是和C语言有更为密切的关系. 这就好比做衣服,C run-time library是为C语言量身定做的,别人或许可以穿,但大小未必合适. 从历史上看,ANSI C是针对C语言制定了C Standard Library的标准形式(包括函数名,调用规则,参数等).即使别的语言可以使用,也必须尊从C run-time library的调用规则. 另外下面这段代码对C run-time library函数fopen,printf的调用是最自然最直接的,虽然我不熟悉PASCAL,FORTRAN,但我相信如果它们希望调用C run-time library函数fopen,printf,恐怕还要多做一些工作. FILE *stream; ... ... if( (stream = fopen( "data", "r" )) == NULL ) printf( "The file 'data' was not opened/n" ); else printf( "The file 'data' was opened/n" ); ... ... 3)在Windows环境中,一个应用被加载时要经过以下步骤(截取部分说明,请忽略序号,只参照包含C运行时库的说明): ... ... 6.主线程为每个DLL调用_DLLMainCRTStartu() 函数。 当链接DLL时,链接器在生成的DLL文件映象中嵌入了DLL的进入/退出函数的地址。缺省时为,链接器假设进入函数名为:_DLLMainCRTStartup。该函数包含在C run-time library(C运行时库)文件中。 当DLL文件被映射到进程地址空间时,系统实际调用的是该函数_DLLMainCRTStartup, 而不是你的DLLMain函数。该函数执行: a.初始化C run-time library(C运行时库)。 // Do runtime startup initializers. _initterm( &__xi_a, &__xi_z ); ... ... 7.主线程根据EXE文件中的子系统值GUI/(CUI),执行WinMainCRTStartup/(MainCRTStartup) a.得到一个新进程的全部命令行的指针。 b.得到一个新进程的环境变量指针。 c.通过STDLIB.H来初始化能被应用访问的C run-time library(C运行时库)全局变量。例如 _osver, _winmajor, _winminor, _winver, _argc, _argv, _environ. // Do runtime startup initializers. _initterm( __xi_a, __xi_z ); ... ... 所以说C run-time library(C运行时库)中确实包含了针对C run-time library自己的初始化代码,例如初始化C run-time library(C运行时库)全局变量_argc, _argv, _environ. 我不知道在PASCAL,FORTRAN程序中是否可以调用这些全局变量. 仅供参考