CRT 库功能

本主题将介绍各种 .lib 文件,包括 C 运行时库及其关联的编译器选项和预处理器指令。

C 运行时库 (CRT)

以下库包含 C 运行时库函数。

C 运行时库(没有 iostream 或标准 C++ 库)

关联的 DLL

特征

选项

预处理器指令

libcmt.lib

无、静态链接。

多线程、静态链接

/MT

_MT

msvcrt.lib

msvcr120.dll

多线程、动态链接(MSVCR120.DLL 的导入库)。 请注意,如果使用标准 C++ 库,你的程序需要 MSVCP120 才能运行 DLL。

/MD

_MT, _DLL

libcmtd.lib

无、静态链接

多线程、静态链接(调试)

/MTd

_DEBUG, _MT

msvcrtd.lib

msvcr120d.dll

多线程、动态链接(MSVCR120.DLL 的导入库)(调试)。

/MDd

_DEBUG, _MT, _DLL

msvcmrt.lib

无、静态链接

C 运行时静态库。 用于混合的托管/本机代码。

/clr

 

msvcurt.lib

无、静态链接

编译为 100% 纯 MSIL 代码的 C 运行时静态库。 所有代码都遵循 MSIL 的 ECMA URT 规范。

/clr:pure

 

备注

单线程 CRT (libc.lib,libcd.lib)(以前的 /ML/MLd 选项)将不再可用。请改用多线程的 CRT。请参阅多线程库性能

如果从没有编译器选项(可指定 C 运行时库)的命令行链接程序,则链接程序将使用 LIBCMT.LIB。 这与早期版本的 Visual C++ 不同,早期版本使用的 LIBC.LIB 是单线程库。

使用静态链接的 CRT 意味着由 C 运行时库保存的任何状态信息对于 CRT 的该实例而言是本地的。 例如,如果当使用静态链接的 CRT 时使用 strtok、_strtok_l、wcstok、_wcstok_l、_mbstok、_mbstok_l,则 strtok 分析器的位置将与链接到另一个静态 CRT 实例的同一进程(但在不同的 DLL 或 EXE 中)的代码中使用的 strtok 状态无关。 相反,动态链接的 CRT 可共享动态链接到 CRT 的进程中的所有代码的状态。 如果使用这些函数新的更安全版本,这一问题则不适用;例如,strtok_s 就不存在此问题。

由于通过链接到静态 CRT 构建的 DLL 将具有其自己的 CRT 状态,因此不建议以静态方式链接到 DLL 中的 CRT,除非特别需要和需了解这一后果。 例如,如果在加载 DLL(链接到其自己的静态 CRT)的可执行文件中调用 _set_se_translator,则转换器将不会捕获由 DLL 中的代码生成的任何硬件异常,但会捕获由主可执行文件中的代码生成的硬件异常。

如果使用 /clr 编译器开关,则将通过静态库 msvcmrt.lib 链接代码。 静态库将提供托管的代码和本机 CRT 之间的代理。 你无法使用静态链接的 CRT(/MT/MTd 选项)和 /clr。 请改用动态链接的库(/MD/MDd)。

如果使用 /clr:pure 编译器开关,则代码将与静态库 msvcurt.lib 链接。 与 /clr 一样,你不能与静态链接的库链接。

有关将 CRT 和 /clr 并行使用的详细信息,请参阅 混合(本机和托管)程序集;对于 /clr:pure,请参阅 纯代码和可验证代码 (C++/CLI)

若要生成你的应用程序的调试版本,则必须定义 _DEBUG 标志,并且该应用程序必须与其中一个调试版本的库链接。 有关使用调试版本的库文件的详细信息,请参阅 CRT 调试技术

此版本的 Visual C++ 不符合 C99 标准。

标准 C++ 库

标准 C++ 库

特征

选项

预处理器指令

LIBCPMT.LIB

多线程、静态链接

/MT

_MT

MSVCPRT.LIB

多线程、动态链接(MSVCP120.dll 的导入库)

/MD

_MT, _DLL

LIBCPMTD.LIB

多线程、静态链接

/MTd

_DEBUG, _MT

MSVCPRTD.LIB

多线程、动态链接(MSVCP120D.DLL 的导入库)

/MDd

_DEBUG, _MT, _DLL

请注意,已删除 LIBCP.LIB 和 LIBCPD.LIB(通过旧的 /ML/MLd 选项)。 请通过 /MT/MTd 选项改用 LIBCPMT.LIB 和 LIBCPMTD.LIB。

当构建项目的发行版时,默认情况下,将链接其中一个基本 C 运行时库(LIBCMT.LIB、MSVCMRT.LIB、MSVCRT.LIB),具体取决于你选择的编译器选项(多线程、DLL、/clr)。 如果在代码中包含其中一个C++ 标准库头文件,则将在编译时通过 Visual C++ 自动链接标准 C + + 库。 例如:

#include <ios> 

若要更改在 Visual Studio 中链接的基本 C 运行时库,请打开项目的属性页。 打开“配置属性”、“C/C++”、“代码生成”页并更改“运行时库”设置。 若要更改公共语言运行时库,请打开项目的属性页。 打开“配置属性”、“C/C + +”、“常规”页,然后更改“公共语言运行时支持”设置。

Msvcrt.dll 和 msvcr120.dll 之间的区别是什么?

Msvcrt.dll 现在是“已知的 DLL”,意思是它是由 Windows 生成并拥有的系统组件。 将来仅供系统级别的组件使用。

如果应用程序同时使用 msvcrt.dll 和 msvcr120.dll,将存在什么问题?

如果具有需要链接到 msvcrt.lib 的 .lib 或 .obj 文件,则不必对其进行重新编译就可使用 Visual C++ 中新的 msvcrt.lib。 .Lib 或.obj 文件可能依赖于各种 CRT 类或变量的大小、字段偏移量或成员函数名称,它们应仍以兼容模式存在。 当针对 msvcrt.lib 重新链接时,最终的 EXE 和 DLL 映像现在将依赖 msvcr120.dll 而不是 msvcrt.dll。

如果有多个 DLL 或 EXE,则无论是否正在使用不同版本的 Visual C++,你都可以具有多个 CRT。 例如,将 CRT 静态链接到多个 Dll 可能存在相同的问题。 遇到此静态 CRT 问题的开发人员已被告知使用 /MD 进行编译,以便使用 CRT DLL。 现在,CRT DLL 已更名为 msvcr120.dll,应用程序可能具有链接到 msvcrt.dll 的某些组件和链接到 msvcr120.dll 其他组件。 如果 Dll 跨 msvcrt.dll 和 msvcr120.dll 边界传递 CRT 资源,将会遇到与 CRT 不匹配的问题,需要使用 Visual C + + 重新编译项目。

如果程序使用多个版本的 CRT,则跨 DLL 边界传递某些 CRT 对象(如文件句柄、区域设置和环境变量)时需注意。 有关所涉及问题及其解决方法的详细信息,请参阅跨 DLL 边界传递 CRT 对象时可能的错误

请参见

其他资源

C 运行时库参考