运行时库(Runtime library)通俗的说就是我们的程序运行的时候所依赖的库文件。在 Windows 平台,这些库由微软提供,并以 2 种形式提供:静态库(lib)动态库(lib+dll),每个库还分别提供了 Debug 和 Release 两个版本。

一、什么是运行时库

C/C++运行时库从形式上来讲和我们自己开发的静态库、动态库没什么两样,只是它们由微软开发和维护,并提供了一些常用的功能支持(如malloc, free, printf等等),如果我们的程序需要使用这些功能(事实上,只要是 C/C++程序就一定会用到运行时库提供的功能),就要链接 C/C++运行时库。我们可以自主选择是链接“静态库”还是“动态库”,是链接“debug 版本”的还是“release 版本”的。

二、如何链接运行时库

大家可能注意到我们在平时开发中从来没有显式的来链接这些库,这是为什么了?
因为我们的编译器为我们提供了便利,我们只需要向编译器指定特定的编译选项(如MT、MD、MTd、MDd),编译器就会自动链接对应的库。

同时,编译器会根据MTMD来定义相应的预处理宏:MT 对应 _MT宏MD对应_MD宏

例如,我们通过Visual Studio开发 C/C++程序时,在工程属性中配置“运行库”为MT、MD、MTd、MDd中的一个:

就相当于间接的向编译器指定编译选项和定义相应的宏。

三、不同版本和形态的运行时库

3.1 运行时库对应的文件

下表列出各种编译选项的含义以及对应的库文件:

类型 全称 含义 对应的库文件 备注
ML Single-Threaded Release 版的单线程静态库 libc.lib 从 VS2005 起被废弃
MLd Single-Threaded Debug Debug 版的单线程静态库 libcd.lib 从 VS2005 起被废弃
MT Multi-threaded Release 版的多线程静态库 libcmt.lib
MTd Multi-threaded Debug Debug 版的多线程静态库 libcmtd.lib
MD Multi-threaded DLL Release 版的多线程动态库 msvcrt.lib + msvcrxxx.dll msvcprt.lib+msvcpxxx.dll
MDd Multi-threaded DLL Debug Debug 版的多线程动态库 msvcrtd.lib + msvcrxxxd.dll msvcprtd.lib + msvcpxxxd.dll

如果计算机上安装了多个版本的 VC++运行环境(或者多个版本的 Visual Studio),则相同名称的 lib 或 dll 就会存在多份。如msvcrt.lib文件:

3.2 运行时库文件命名规则

msvcr100d.dll为例:

1
2
3
4
5
6
ms = Microsoft
v = Visual
c = C Program
r = Run-time
100 = Version
d = Debug (不带d即为release版本)

msvcp100d.dll为例:

1
2
3
4
5
ms = Microsoft
v = Visual
cp = C Plus Plus 即C++
100 = Version
d = Debug (不带d即为release版本)

四、运行时库使用注意事项

  • 不要混合使用运行时库的静态库版动态库版
  • 不要混合使用运行时库的debug版release版
  • 不要混合使用 Visual Studio 2013 及更早版本的运行时库,但在 Visual Studio 2015 及更高版本中提供的运行时库可以保证二进制兼容。

五、Visual Studio 版本之间的 C++ 二进制兼容性(摘自 MSDN)

原文链接:binary-compat-2015-2017

Visual Studio 2013 及更早版本中的 Microsoft C++ (MSVC) 编译器工具集不保证主版本间的二进制兼容性。 无法链接由这些工具集的不同版本生成的对象文件、静态库、动态库和可执行文件。 ABI、对象格式和运行时库不兼容。

我们在 Visual Studio 2015 及更高版本中改变了此行为。 由其中任一版本的编译器编译的运行时库和应用具有二进制兼容性。 这反映在 C++ 工具集主版本号中,对于自 Visual Studio 2015 以来的所有版本,该版本号都以 14 开头。 (对于 Visual Studio 2015、2017、2019 和 2022,工具集版本分别为 v140、v141、v142 和 v143)。** 假设你具有 Visual Studio 2015 生成的第三方库。 你仍可在 Visual Studio 2017、2019 或 2022 生成的应用程序中使用它们。 无需使用匹配工具集重新编译**。 最新版本的 Microsoft Visual C++ 可再发行程序包(可再发行程序包)适用于所有版本。

对二进制兼容性的限制

v140、v141、v142 和 v143 工具集与次要版本号更新之间的二进制兼容性方面存在三个重要限制:

  • 你可以混合使用由 v140、v141、v142 和 v143 工具集的不同版本生成的二进制文件。 但是,必须使用至少与应用中最新二进制文件同样新的工具集进行链接。 下面是一个示例:可以将使用任何 2017 工具集(v141,版本 15.0 到 15.9)编译的应用链接到使用 Visual Studio 2019 版本 16.2 (v142) 编译的静态库。 只是必须使用版本 16.2 或更高版本工具集链接它们。 只要使用 16.4 或更高版本工具集,便可以将版本 16.2 库链接到版本 16.4 应用。
  • 应用使用的可再发行程序包具有类似的二进制兼容性限制。 混合使用由工具集的不同受支持版本生成的二进制文件时,可再发行程序包版本必须至少与任何应用组件使用的最新工具集一样新。
  • 使用/GL(全程序优化)编译器开关编译或是使用 /LTCG(链接时间代码生成)链接的静态库或对象文件不在各个版本间二进制兼容(包括次要版本更新)。使用 /GL/LTCG 编译的所有对象文件和库必须将完全相同的工具集用于编译和最终链接。 例如,使用 Visual Studio 2019 版本 16.7 工具集中的 /GL生成的代码无法链接到使用 Visual Studio 2019 版本 16.8 工具集中的 /GL生成的代码。 编译器会发出错误 C1047

从 Visual Studio 2015 及更高版本升级 Microsoft Visual C++ 可再发行程序包

对于 Visual Studio 2015、2017、2019 和 2022,我们使 Microsoft Visual C++ 可再发行程序包主版本号保持相同。 这意味着一次只能安装可再发行程序包的一个实例。 较新版本会覆盖已安装的任何较旧版本。 例如,一个应用可能会从 Visual Studio 2015 安装可再发行程序包。 随后另一个应用从 Visual Studio 2022 安装可再发行程序包。 2022 版本会覆盖较旧版本,但由于它们具有二进制兼容性,早期应用仍可正常工作。 我们确保最新版本的可再发行程序包具有所有最新的功能、安全更新和 bug 修补程序。 这便是为什么我们始终建议升级到最新可用版本。

同样,已安装了较新版本时,无法安装较旧的可再发行程序包。 如果尝试,则安装程序会报告错误。 如果在已具有 2022 版本的计算机上安装 2017 或 2019 可再发行程序,则会看到如下所示的错误:

1
0x80070666 - Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.

此错误是设计使然。 建议保持安装最新版本。 请确保安装程序可以在无提示的情况下从此错误中恢复。

文章图片带有“CSDN”水印的说明:
由于该文章和图片最初发表在我的CSDN 博客中,因此图片被 CSDN 自动添加了水印。