嗯,我明白了,但是比如说,
libcmt.lib
中有什么?它是做什么的?我原本以为C标准库是C编译器的一部分。那么libcmt.lib
是Windows下实现C标准库函数以在win32下工作的吗?libcmt.lib
中有什么?它是做什么的?我原本以为C标准库是C编译器的一部分。那么libcmt.lib
是Windows下实现C标准库函数以在win32下工作的吗?是的,libcmt是微软编译器提供的C标准库的(多个)实现之一。它们提供三种基本类型的库的“调试”和“发布”版本: 单线程(总是静态链接),多线程静态链接和多线程动态链接(但是根据您使用的编译器版本,其中一些可能不存在)。
所以,在名称“libcmt”中,“libc”是 C 库的传统名称。 “mt”表示“多线程”。 “调试”版本会在结尾加上“d”,得到“libcmtd”。
至于它包含哪些函数,C 标准(第 7 部分,如果您恰好关心)定义了符合(托管)实现必须提供的函数集。大多数供应商(包括 Microsoft)自己添加各种其他功能(用于兼容性,提供标准函数未涉及的功能等)。在大多数情况下,它还包含许多“内部”函数,这些函数由编译器使用,但终端用户通常不使用。
运行时库基本上是一个将这些函数的实现收集到一个大文件中(或者几个大文件 - 例如,在 UNIX 上,浮点函数通常存储在与其余函数分开的地方)的集合。该大文件通常是与 zip 文件相同的量级,但没有任何压缩,因此它只是一些小文件集合,并存储在一个大文件中。档案通常至少包含一些索引,以使从内部文件中查找和提取数据相对快速/容易。至少在某些情况下,微软使用了具有“扩展”索引的库格式,链接器可以使用该索引找到哪些函数实现在子文件中,因此它可以更快地找到并链接其需要的部分(但这纯粹是一种优化,而不是要求)。
如果你想获取“libcmt”(以您的示例为例)中所有函数的完整列表,可以打开Visual Studio命令提示符之一(通常在“Visual Studio工具”下),切换到库安装目录并输入以下命令:lib -list libcmt.lib
,它将生成一个(很长的)列表,其中列出了该库中所有对象文件的名称。它们不总是直接对应于函数的名称,但通常会给出一个大致的概念。如果您想查看特定对象文件,可以使用lib -extract
提取其中一个对象文件,然后使用dumpbin /symbols <object file name>
查找该特定对象文件中的哪个函数。
在编程语言C中,每个程序都从main()
函数开始执行。其他语言可能会定义其他函数作为程序的起点。但处理器并不知道main()
函数。处理器只知道预定义的命令,由0
和1
的组合表示。
在微处理器编程中,如果没有底层操作系统(如Microsoft Windows、Linux、MacOS等),您需要通过设置程序计数器(PC)来显式告诉处理器从哪里开始运行程序。PC会在处理器已知的命令之间进行迭代和跳转(循环、函数调用)。您需要知道RAM的大小,设置程序堆栈(本地变量)的位置,以及堆(动态变量)和全局变量(我猜它被称为SSA?)在RAM内的位置。单个处理器一次只能执行一个程序。
这就是操作系统发挥作用的地方。操作系统本身是在处理器上运行的程序,它允许执行自定义代码。通过在多个程序之间切换执行代码(这些代码加载到RAM中),同时运行多个程序。但是操作系统本身也是一个程序,每个程序都是以不同的方式编写的。仅将自定义程序代码放入RAM中并不能运行它,因为操作系统并不知道它。您需要调用操作系统的功能来注册您的程序,告诉操作系统程序需要多少内存,程序入口点位于何处(在C语言中为main()
函数)。我猜这就是运行时库所在的位置,并解释了为什么每个操作系统都需要一个特殊的库,因为这些库本身也是程序,具有不同的功能来完成这些任务。
C语言是一种语言,它的定义中并不需要为您提供任何函数。没有IO、没有数学例程等等。按照惯例,有一组可用于链接到您的可执行文件的例程,但您不必必须使用它们。然而,这是一个非常普遍的做法,以至于大多数链接器不再要求您链接到C运行时库。
有时候您可能不需要这些函数——例如,在嵌入式系统中工作时,可能无法使用malloc(动态内存分配)等函数。我曾经在打印机上嵌入PostScript,我们有自己的运行时库,适用于嵌入式系统,因此我们没有使用“标准”运行时库。
运行时库是自动编译进任何C程序中的库。所使用的库的版本取决于编译器、平台、调试选项和多线程选项。
关于不同运行时库选择的良好描述:http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html
它包括那些通常不需要调用库来调用的函数:
Microsoft有一个他们的运行时库函数的很好的列表:
函数的确切列表会因编译器而异,因此对于iOS,您将获得其他函数,如dispatch_async()或NSLog()。
struct
和enum
只是typedefs,基本上只是一种使用基本类型(如unsigned int
、long
和signed short
)更加逻辑和结构化的语法糖。你根本不需要任何库代码或文本,因为它们在实际的二进制可执行文件中不存在!每个枚举值只是一个普通的数字,每个结构体字段只是用原始数据填充--结构体字段的“含义”是源代码概念,在二进制可执行文件或目标文件中根本不存在。 - Gregory Fenn标准C运行时库的微软实现提供了...
Win32 SDK提供了三种C运行时库:
* LIBC.LIB is a statically linked library for single-threaded programs.
* LIBCMT.LIB is a statically linked library that supports multithreaded programs.
* CRTDLL.LIB is an import library for CRTDLL.DLL that also supports multithreaded programs. CRTDLL.DLL itself is part of Windows NT.
微软Visual C++ 32位版也包含这三种形式,但是在DLL中的CRT命名为MSVCRT.LIB。该DLL可重新分发。它的名称取决于VC++的版本(即MSVCRT10.DLL或MSVCRT20.DLL)。但请注意,MSVCRT10.DLL不支持Win32s,而CRTDLL.LIB支持Win32s。MSVCRT20.DLL有两个版本:一个用于Windows NT,另一个用于Win32s。
参见:http://support.microsoft.com/?scid=kb%3Ben-us%3B94248&x=12&y=9