什么是C运行时库?


157

C运行时库实际上是什么,它的作用是什么?我一直在搜索,就像恶魔一样,但是没有找到比微软更好的东西:“微软运行时库提供了用于Microsoft Windows操作系统编程的例程。这些例程可自动执行许多常规编程任务,而这些任务并非由Microsoft提供C和C ++语言。”

好,我明白了,但是例如,里面有什么libcmt.lib?它有什么作用?我认为C标准库是C编译器的一部分。那么libcmt.libWindows的C标准库功能实现是否可以在win32下工作?

Answers:


71

是的,libcmt是Microsoft编译器提供的C标准库的(几种)实现之一。它们提供三种基本类型的库的“调试”和“发行”版本:单线程(始终静态链接),多线程静态链接多线程动态链接(尽管取决于您使用的编译器版本)使用,其中一些可能不存在)。

因此,在名称“ libcmt”中,“ libc”是(或多或少)C库的传统名称。“ mt”表示“多线程”。“调试”版本的末尾将添加“ d”,从而得到“ libcmtd”。

就其包含的功能而言,C标准(如果您很在意,请参见第7部分)定义了一组合格的(托管)实现必须提供的功能。大多数供应商(包括Microsoft)本身都会添加其他各种功能(出于兼容性,提供标准功能无法解决的功能等)。在大多数情况下,它还将包含许多编译器使用的“内部”功能但最终用户通常不会。

如果要在“ libcmt”中获得功能的完整列表(以使用示例为例),可以打开一个Visual Studio命令提示符(通常在“ Visual Studio Tools”下),切换到库所在的目录安装,然后键入类似的内容:lib -list libcmt.lib它将生成该库中所有目标文件名称的()列表。这些并不总是直接对应于函数的名称,但是通常会给出一个想法。如果要查看特定的目标文件,可以使用lib -extract提取这些目标文件之一,然后使用dumpbin /symbols <object file name>查找该特定目标文件中的功能。


37
您还没有告诉我们“ C运行时库”是什么!
onmyway133'4

4
@entropy:当然,对我来说就像我一样,但是简短的答案是它是一个函数集合,其中许多(但不一定是全部)在C标准的第7部分中指定。
杰里·科芬

3
这个答案暗示C库只是编译器工具链的一部分。不准确。
jiggunjer

@JerryCoffin问题:那么strcpy,例如,来自C标准库的函数是在运行时库中实现该函数,还是仅将其代码包含在常规.c文件中?
forumulator

@forumulator:.c文件中通常会有源代码,这些源代码会被编译以生成适当的标准库(..dll,lib,.a,.so或适用于您所使用系统的任何内容) 。
杰里·科芬

55

首先,我们应该了解什么是运行库。并考虑“ Microsoft C运行时库”的含义。

请参阅:http : //en.wikipedia.org/wiki/Runtime_library

我将大多数文章发布在这里,因为它可能会被更新。

当计算机程序的源代码由编译器翻译成相应的目标语言时,如果程序中的每个命令和对内置函数的每个调用都将导致就地生成,则将导致程序代码的极大扩展。每次都以目标语言显示完整的相应程序代码。相反,编译器通常在运行时库中使用编译器特定的辅助功能,而这些功能通常是应用程序程序员无法访问的。根据编译器制造商的不同,运行时库有时还会包含相应编译器的标准库或包含在其中。

在运行时库中还实现了一些只能在运​​行时执行的功能(或更高效或更准确),例如某些逻辑错误,数组边界检查,动态类型检查,异常处理以及可能的调试功能。因此,尽管进行了复杂的编译时检查和预发布测试,但是直到在具有真实数据的“实时”环境中测试程序后,才发现一些编程错误。在这种情况下,最终用户可能会遇到运行时错误消息。

通常,运行时库通过访问操作系统来实现许多功能。许多编程语言具有内置功能,这些功能不一定必须在编译器中实现,而可以在运行时库中实现。因此,运行时库和标准库之间的界限取决于编译器制造商。因此,运行时库始终是特定于编译器和特定于平台的。

运行时库的概念不应与普通程序库(例如由应用程序程序员创建或由第三方或动态库交付的程序库)混淆,后者是指在运行时链接的程序库。例如,编程语言C仅需要最小的运行时库(通常称为crt0),但定义了每个实现必须交付的大型标准库(称为C标准库)。


3
高亮显示的句子是区别于标准库的一种方式,是我所见过的第一个简洁准确的答案,我没有用“大多数”或“有时”来限定。
nik.shornikov

@ nik.shornikov:这是因为其他描述试图更加准确。虽然这是真的,一个标准库是典型的特定于编译器和平台,这并非总是如此。仅举例来说,Mingw和用于Windows的英特尔C ++编译器的至少某些版本使用了Microsoft的标准库,而不是提供它们自己的库。同样,可以(并且经常)安装Linux上的Clang,以在现有gcc安装中使用标准库,而不必自己安装另一个。
杰里·科芬

我可以肯定地说,可以编写可移植到任何支持POSIX的平台的C和C ++标准库的实现。
杰里·科芬

20

我自己问了这个问题,并且伤了我几个小时的大脑。仍然没有发现任何真正有意义的东西。每个确实为主题写过东西的人都无法真正“教”。如果要教某人,请使用该人能理解的最基本的语言,因此他在处理某个主题时无需关心其他主题。因此,我为自己得出了一个结论,该结论似乎很适合所有这些混乱情况。

在编程语言C中,每个程序都以main()函数开头。其他语言可能会在程序启动时定义其他功能。但是处理器不知道main()。处理器仅知道由“ 0”和“ 1”的组合表示的预定义命令。

在没有底层操作系统(Microsoft Windows,Linux,MacOS等)的微处理器编程中,您需要通过设置在其中进行迭代和跳转(循环,函数调用)的ProgrammCounter(PC)来明确告诉处理器从哪里开始。处理器已知的命令。您需要知道RAM的大小,需要设置程序堆栈的位置(局部变量),以及堆的位置(动态变量)和全局变量的位置(我猜它被称为SSA) ?)在RAM中。单个处理器一次只能执行一个程序。

那就是操作系统的所在。操作系统本身是在处理器上运行的程序。允许执行自定义代码的程序。通过在程序的执行代码(已加载到RAM中)之间切换来一次运行多个程序。但是操作系统是一个程序,每个程序的编写方式不同。只是将自定义程序的代码放入RAM不会运行它,操作系统也不知道。您需要在注册程序的操作系统上调用函数,告诉操作系统程序需要多少内存,以及程序入口的位置(在C中为main()函数)。我猜这是在RuntimeLibrary中,它解释了为什么每个操作系统都需要一个特殊的库,

这也解释了为什么它在运行时不像.dll文件那样动态链接,即使它被称为RUNTIMELibrary。RuntimeLibrary需要静态链接,因为在程序启动时需要它。RuntimeLibrary确实在RUNTIME将自定义程序插入/连接到另一个程序(操作系统)。这个现实会引起一些大脑疲劳。

结论:RUNTIMELibrary命名失败。早期可能没有.dll(运行时链接),并且根本不存在理解差异的问题。但是,即使这是真的,也很难选择名称。

更好的RuntimeLibrary名称可以是:StartupLibrary / OSEntryLibrary / SystemConnectLibrary / OSConnectLibrary

希望我做对了,为纠正/扩展欢呼声。


1
我仍然没有意识形态。为什么程序在运行时需要一些东西?为什么二进制代码不能在运行时没有任何支持的情况下单独运行100%?或换句话说:是否可能有一个可以在没有任何内容的情况下100%运行的代码(包括OS)?
MarcioAB

5
从理论上讲,程序不需要 RTL。但是,如果没有操作系统的某些配合,您的程序将如何显示结果或接受任何输入或请求内存?
SN

16

C是一种语言,在其定义中,不需要任何可用功能。没有IO,没有数学例程,等等。按照惯例,您可以使用一组例程,这些例程可以链接到可执行文件中,但是您无需使用它们。但是,这是很常见的事情,大多数链接器不再要求您链接到C运行时库。

有时候您不希望使用它们,例如,在嵌入式系统中,使用malloc可能不切实际。我过去曾致力于将PostScript嵌入打印机中,而我们拥有自己的运行时库集,这些库在嵌入式系统上要快乐得多,因此我们不必理会“标准”。


11
实际上,C标准描述了两种类型的C环境-“独立”和“托管”-并且在托管环境中,标准描述的功能定义为可用。在嵌入式系统中,C环境通常是独立的,因此您可能没有库例程,或者您可以避免使用某些例程并使用自己的替代程序。

10

运行时库是针对您运行的任何C程序自动编译的库。您将使用的库版本取决于编译器,平台,调试选项和多线程选项。

不同的选择的运行时库一个很好的说明: http://www.davidlenihan.com/2008/01/choosing_the_correct_cc_runtim.html

它包括那些通常不需要库调用的函数:

  • 分配
  • 枚举,结构
  • 绝对最小
  • 断言

Microsoft提供了很好的运行时库功能列表:

http://msdn.microsoft.com/zh-CN/library/2aza74he(VS.71).aspx

函数的确切列表取决于编译器,因此对于iOS,您将获得其他函数,例如dispatch_async()或NSLog()。


1
struct和enum真的是运行时库吗?
Dean P

6

如果在从C或C ++编译的可执行文件上使用诸如Dependency Walker之类的工具,则会看到它依赖的DLL之一是MSVCRT.DLL。这是Microsoft C运行时库。如果您进一步检查带有DW的MSVCRT.DLL,您会发现这是所有函数(如printf(),puts(0,gets(),atoi()等)都存在的地方。


6
仅当编译该可执行文件时,C运行时才被动态链接。如果它是静态链接的,则依赖项遍历器将显示出什么都不是
Eli Bendersky 2010年

4

我认为微软的定义的真正含义是:

标准C运行时库的Microsoft实现提供了...


3

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. 

Microsoft Visual C ++ 32位版本也包含这三种形式,但是,DLL中的CRT名为MSVCRT.LIB。DLL是可再发行的。其名称取决于VC ++的版本(即MSVCRT10.DLL或MSVCRT20.DLL)。但是请注意,Win32s不支持MSVCRT10.DLL,而Win32s不支持CRTDLL.LIB。MSVCRT20.DLL有两个版本:一个用于Windows NT,另一个用于Win32s。

请参阅:http : //support.microsoft.com/?scid=kb%3Ben-us%3B94248&x=12&y=9

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.