什么是 C 运行时库?
C 运行时库到底是什么以及它的用途是什么?我像魔鬼一样在谷歌上搜索,但我找不到比微软更好的东西:“微软运行时库提供了为微软Windows操作系统编程的例程。这些例程自动执行了许多常见的编程任务,而这些任务是由Microsoft提供的。 C 和 C++ 语言。”
好的,我明白了,但是例如,libcmt.lib
中有什么?它有什么作用?我认为C标准库是C编译器的一部分。那么libcmt.lib
Windows对C标准库函数的实现可以在win32下工作吗?
What actually is a C runtime library and what is it used for? I was searching, Googling like a devil, but I couldn't find anything better than Microsoft's: "The Microsoft run-time library provides routines for programming for the Microsoft Windows operating system. These routines automate many common programming tasks that are not provided by the C and C++ languages."
OK, I get that, but for example, what is in libcmt.lib
? What does it do? I thought that the C standard library was a part of C compiler. So is libcmt.lib
Windows' implementation of C standard library functions to work under win32?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是的,libcmt 是 Microsoft 编译器提供的 C 标准库的(几个)实现。它们提供三种基本类型库的“调试”和“发布”版本:单线程(始终静态链接)、多线程静态链接和 >多线程动态链接(不过,根据您使用的编译器版本,其中一些可能不存在)。
因此,在名称“libcmt”中,“libc”是(或多或少)C 库的传统名称。 “mt”的意思是“多线程”。 “调试”版本将在末尾添加“d”,给出“libcmtd”。
至于它包含哪些函数,C 标准(第 7 部分,如果您关心的话)定义了一组符合(托管)实现必须提供的函数。大多数供应商(包括 Microsoft)自己添加各种其他函数(为了兼容性、提供标准函数未解决的功能等)。在大多数情况下,它还将包含编译器使用的相当多的“内部”函数但通常不是由最终用户执行的。
运行时库基本上是一个大文件(或几个大文件,例如,在 UNIX 上,浮点函数传统上与其余函数分开存储)中这些函数的实现的集合。该大文件通常与 zip 文件具有相同的一般顺序,但没有任何压缩,因此它基本上只是一些收集在一起的小文件,并一起存储到一个更大的文件中。存档通常至少包含一些索引,以便相对快速/轻松地从内部文件中查找和提取数据。至少有时,微软使用了带有“扩展”索引的库格式,链接器可以使用它来查找哪些函数在哪些子文件中实现,因此它可以更快地找到并链接它需要的部分(但那是纯粹是优化,不是要求)。
如果您想获得“libcmt”中函数的完整列表(以使用您的示例),您可以打开 Visual Studio 命令提示符之一(通常在“Visual Studio Tools”下),切换到库所在的目录安装后,输入如下内容:
lib -list libcmt.lib
,它将生成该库中所有目标文件名称的(长)列表。这些并不总是直接对应于函数的名称,但通常会给出一个想法。如果您想查看特定的目标文件,可以使用 lib -extract 提取其中一个目标文件,然后使用 dumpbin /symbols <目标文件名>查找该特定目标文件中的函数。Yes, libcmt is (one of several) implementations of the C standard library provided with Microsoft's compiler. They provide both "debug" and "release" versions of three basic types of libraries: single-threaded (always statically linked), multi-threaded statically linked, and multi-threaded dynamically linked (though, depending on the compiler version you're using, some of those may not be present).
So, in the name "libcmt", "libc" is the (more or less) traditional name for the C library. The "mt" means "multi-threaded". A "debug" version would have a "d" added to the end, giving "libcmtd".
As far as what functions it includes, the C standard (part 7, if you happen to care) defines a set of functions a conforming (hosted) implementation must supply. Most vendors (including Microsoft) add various other functions themselves (for compatibility, to provide capabilities the standard functions don't address, etc.) In most cases, it will also contain quite a few "internal" functions that are used by the compiler but not normally by the end user.
The runtime library is basically a collection of the implementations of those functions in one big file (or a few big files--e.g., on UNIX the floating point functions are traditionally stored separately from the rest). That big file is typically something on the same general order as a zip file, but without any compression, so it's basically just some little files collected together and stored together into one bigger file. The archive will usually contain at least some indexing to make it relatively fast/easy to find and extract the data from the internal files. At least at times, Microsoft has used a library format with an "extended" index the linker can use to find which functions are implemented in which of the sub-files, so it can find and link in the parts it needs faster (but that's purely an optimization, not a requirement).
If you want to get a complete list of the functions in "libcmt" (to use your example) you could open one of the Visual Studio command prompts (under "Visual Studio Tools", normally), switch to the directory where your libraries were installed, and type something like:
lib -list libcmt.lib
and it'll generate a (long) list of the names of all the object files in that library. Those don't always correspond directly to the names of the functions, but will generally give an idea. If you want to look at a particular object file, you can uselib -extract
to extract one of those object files, then usedumpbin /symbols <object file name>
to find what function(s) is/are in that particular object file.首先,我们应该了解什么是运行时库;并思考“Microsoft C 运行时库”的含义。
请参阅:http://en.wikipedia.org/wiki/Runtime_library
我已将大部分文章发布在这里,因为它可能得到更新。
At first, we should understand what a Runtime Library is; and think what it could mean by "Microsoft C Runtime Library".
see: http://en.wikipedia.org/wiki/Runtime_library
I have posted most of the article here because it might get updated.
我自己问了这个问题,几个小时以来我的大脑都在受伤。仍然没有找到任何真正有意义的东西。每个为某个主题写一些东西的人都无法真正“教学”。如果你想教一个人,就用一个人听得懂的最基本的语言,这样他在处理一个话题时就不需要关心其他话题。所以我自己得出了一个似乎很适合所有这些混乱的结论。
在编程语言 C 中,每个程序都以
main()
函数开始。其他语言可能会在程序启动时定义其他函数。但处理器不知道
main()
。处理器只知道由0
和1
的组合表示的预定义命令。在微处理器编程中,没有底层操作系统(Microsoft Windows、Linux、MacOS 等),您需要通过设置迭代和跳转的 ProgramCounter (PC) 来明确告诉处理器从哪里开始(循环、函数调用)在处理器已知的命令内。你需要知道RAM有多大,你需要设置程序堆栈(局部变量)的位置,以及堆(动态变量)的位置和全局变量的位置(我猜它叫SSA ?)在RAM中。
单个处理器一次只能执行一个程序。
这就是操作系统的用武之地。操作系统本身是一个在处理器上运行的程序。允许执行自定义代码的程序。通过在程序的执行代码(加载到 RAM 中)之间切换来一次运行多个程序。但操作系统是一个程序,每个程序的编写方式都不同。简单地将自定义程序的代码放入 RAM 中是无法运行的,操作系统并不知道这一点。您需要调用操作系统上注册您的程序的函数,告诉操作系统该程序需要多少内存,程序的入口点位于何处(如果是,则为
main()
函数) C)。我猜这就是运行时库中的内容,并解释了为什么每个操作系统都需要一个特殊的库,因为这些只是程序本身,并且具有不同的功能来完成这些事情。这也解释了为什么它不像
.dll
文件那样在运行时动态链接,即使它被称为运行时库。运行时库需要静态链接,因为在程序启动时需要它。运行时库在运行时将您的自定义程序注入/连接到另一个程序(操作系统)。这确实引起了一些脑残……结论:
RUNTIME 库的命名是失败的。早期可能不存在
.dll
(在运行时链接),并且根本不存在理解差异的问题。但即使这是真的,这个名字也选得很糟糕。运行时库的更好名称可能是:StartupLibrary/OSEntryLibrary/SystemConnectLibrary/OSConnectLibrary
希望我做对了,以便进行更正/扩展。
干杯。
I just asked this myself and was hurting my brain for some hours. Still did not find anything that really makes a point. Everybody that does write something to a topic is not able to actually "teach". If you want to teach someone, take the most basic language a person understands, so he does not need to care about other topics when handling a topic. So I came to a conclusion for myself that seems to fit well in all this chaos.
In the programming language C, every program starts with the
main()
function.Other languages might define other functions where the program starts. But a processor does not know the
main()
. A processor knows only predefined commands, represented by combinations of0
and1
.In microprocessor programming, not having an underlying operating system (Microsoft Windows, Linux, MacOS,..), you need to tell the processor explicitly where to start by setting the
ProgramCounter
(PC) that iterates and jumps (loops, function calls) within the commands known to the processor. You need to know how big the RAM is, you need to set the position of the program stack (local variables), as well as the position of the heap (dynamic variables) and the location of global variables (I guess it was called SSA?) within the RAM.A single processor can only execute one program at a time.
That's where the operating system comes in. The operating system itself is a program that runs on the processor. A program that allows the execution of custom code. Runs multiple programs at a time by switching between the execution codes of the programs (which are loaded into the RAM). But the operating system IS A PROGRAM, each program is written differently. Simply putting the code of your custom program into RAM will not run it, the operating system does not know it. You need to call functions on the operating system that registers your program, tell the operating system how much memory the program needs, where the entry point into the program is located (the
main()
function in case of C). And this is what I guess is located within the Runtime Library, and explains why you need a special library for each operating system, cause these are just programs themselves and have different functions to do these things.This also explains why it is NOT dynamically linked at runtime as
.dll
files are, even if it is called a RUNTIME Library. The Runtime Library needs to be linked statically, because it is needed at startup of your program. The Runtime Library injects/connects your custom program into/to another program (the operating system) at RUNTIME. This really causes some brain f...Conclusion:
RUNTIME Library is a fail in naming. There might not have been a
.dll
(linking at runtime) in the early times and the issue of understanding the difference simply did not exist. But even if this is true, the name is badly chosen.Better names for the Runtime Library could be: StartupLibrary/OSEntryLibrary/SystemConnectLibrary/OSConnectLibrary
Hope I got it right, up for correction/expansion.
cheers.
C 是一种语言,根据其定义,不需要有任何可用的函数。没有IO,没有数学例程等等。按照惯例,有一组可用的例程可供您链接到可执行文件中,但您不需要使用它们。然而,这是一件很常见的事情,大多数链接器不再要求您链接到 C 运行时库。
有时您不需要它们 - 例如,在使用嵌入式系统时,使用 malloc 可能是不切实际的。我曾经致力于将 PostScript 嵌入到打印机中,我们有自己的一组运行时库,这些库在嵌入式系统上更受欢迎,所以我们没有为“标准”而烦恼。
C is a language and in its definition, there do not need to be any functions available to you. No IO, no math routines and so on. By convention, there are a set of routines available to you that you can link into your executable, but you don't need to use them. This is, however, such a common thing to do that most linkers don't ask you to link to the C runtime libraries anymore.
There are times when you don't want them - for example, in working with embedded systems, it might be impractical to have malloc, for example. I used to work on embedding PostScript into printers and we had our own set of runtime libraries that were much happier on embedded systems, so we didn't bother with the "standard".
运行时库是为您运行的任何 C 程序自动编译的库。您将使用的库的版本取决于您的编译器、平台、调试选项和多线程选项。
对运行时库的不同选择的良好描述:
http://www.davidlenihan.com/2008/01/choosing_the_ Correct_cc_runtim.html
它包括那些您通常认为不需要库来调用的函数:
Microsoft 有一个很好的运行时库函数列表:
https://learn.microsoft.com/en- us/cpp/c-runtime-library/reference/crt-alphabetical-function-reference?view=msvc-170
函数的确切列表会根据编译器的不同而有所不同,因此对于 iOS,您将获得其他函数,例如dispatch_async () 或 NSLog()。
The runtime library is that library that is automatically compiled in for any C program you run. The version of the library you would use depends on your compiler, platform, debugging options, and multithreading options.
A good description of the different choices for runtime libraries:
http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html
It includes those functions you don't normally think of as needing a library to call:
Microsoft has a nice list of their runtime library functions:
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/crt-alphabetical-function-reference?view=msvc-170
The exact list of functions would vary depending on compiler, so for iOS you would get other functions like dispatch_async() or NSLog().
如果您在从 C 或 C++ 编译的可执行文件上使用 Dependency Walker 等工具,您将看到其中之一它所依赖的DLL是MSVCRT.DLL。这是 Microsoft C 运行时库。如果您使用 DW 进一步检查 MSVCRT.DLL,您会发现这是 printf()、puts(0、gets()、atoi() 等所有函数的所在地。
If you use a tool like Dependency Walker on an executable compiled from C or C++ , you will see that one of the the DLLs it is dependent on is MSVCRT.DLL. This is the Microsoft C Runtime Library. If you further examine MSVCRT.DLL with DW, you will see that this is where all the functions like printf(), puts(0, gets(), atoi() etc. live.
我认为微软的定义真正的意思是:
i think Microsoft's definition really mean:
Win32 SDK 提供了三种形式的 C 运行时库:
Microsoft Visual C++ 32 位版本也包含这三种形式,但是 DLL 中的 CRT 名为 MSVCRT.LIB。该 DLL 是可重新分发的。其名称取决于 VC++ 的版本(即 MSVCRT10.DLL 或 MSVCRT20.DLL)。但请注意,Win32s 不支持 MSVCRT10.DLL,而 Win32s 支持 CRTDLL.LIB。 MSVCRT20.DLL 有两个版本:一个用于 Windows NT,另一个用于 Win32。
请参阅:http://support.microsoft .com/?scid=kb%3Ben-us%3B94248&x=12&y=9
There are three forms of the C Run-time library provided with the Win32 SDK:
Microsoft Visual C++ 32-bit edition contains these three forms as well, however, the CRT in a DLL is named MSVCRT.LIB. The DLL is redistributable. Its name depends on the version of VC++ (ie MSVCRT10.DLL or MSVCRT20.DLL). Note however, that MSVCRT10.DLL is not supported on Win32s, while CRTDLL.LIB is supported on Win32s. MSVCRT20.DLL comes in two versions: one for Windows NT and the other for Win32s.
see: http://support.microsoft.com/?scid=kb%3Ben-us%3B94248&x=12&y=9