CRT 程式庫功能CRT Library Features

本主題討論組成 C 執行階段程式庫的各種 .lib 檔案,以及其相關聯的編譯器選項與前置處理器指示詞。This topic discusses the various .lib files that comprise the C run-time libraries as well as their associated compiler options and preprocessor directives.

C 執行階段程式庫 (CRT)C Run-Time Libraries (CRT)

C 執行階段程式庫 (CRT) 是納入 ISO C99 標準程式庫之 C++ 標準程式庫的一部分。The C Run-time Library (CRT) is the part of the C++ Standard Library that incorporates the ISO C99 standard library. 實作 CRT 的 Visual C++ 程式庫支援機器碼開發,以及混合的機器碼與受控碼。The Visual C++ libraries that implement the CRT support native code development, and both mixed native and managed code. CRT 的所有版本都支援多執行緒開發。All versions of the CRT support multi-threaded development. 大部分程式庫都支援靜態連結和動態連結,靜態連結可將程式庫直接連結到您的程式碼,而動態連結則可讓您的程式碼使用通用 DLL 檔案。Most of the libraries support both static linking, to link the library directly into your code, or dynamic linking to let your code use common DLL files.

自 Visual Studio 2015 起,CRT 已重構為新的二進位檔。Starting in Visual Studio 2015, the CRT has been refactored into new binaries. 通用 CRT (UCRT) 包含標準 C99 CRT 程式庫所匯出的函式和全域變數。The Universal CRT (UCRT) contains the functions and globals exported by the standard C99 CRT library. UCRT 現在是 Windows 元件,而且隨附於 Windows 10。The UCRT is now a Windows component, and ships as part of Windows 10. 靜態程式庫、DLL 匯入程式庫和 UCRT 的標頭檔現在都位於 Windows 10 SDK 中。The static library, DLL import library, and header files for the UCRT are now found in the Windows 10 SDK. 當您安裝 Visual C++ 時,Visual Studio 安裝程式會安裝使用 UCRT 所需的一部分 Windows 10 SDK。When you install Visual C++, Visual Studio setup installs the subset of the Windows 10 SDK required to use the UCRT. 您可以在 Visual Studio 2015 及以上版本支援的任何 Windows 版本上使用 UCRT。You can use the UCRT on any version of Windows supported by Visual Studio 2015 and later versions. 您可以針對 Windows 10 以外的 Windows 支援版本,使用 vcredist 來轉散發。You can redistribute it using vcredist for supported versions of Windows other than Windows 10. 如需詳細資訊,請參閱轉散發 Visual C++ 檔案For more information, see Redistributing Visual C++ Files.

下表列出實作 UCRT 的程式庫。The following table lists the libraries that implement the UCRT.

程式庫Library 相關聯的 DLLAssociated DLL 特性Characteristics 選項Option 前置處理器指示詞Preprocessor directives
libucrt.lib None 以靜態方式將 UCRT 連結到您的程式碼。Statically links the UCRT into your code. /MT _MT
libucrtd.lib None 用於靜態連結的偵錯版 UCRT。Debug version of the UCRT for static linking. 不可轉散發。Not redistributable. /MTd _DEBUG, _MT_DEBUG, _MT
ucrt.lib ucrtbase.dll UCRT 的 DLL 匯入程式庫。DLL import library for the UCRT. /MD _MT, _DLL_MT, _DLL
ucrtd.lib ucrtbased.dll 偵錯版 UCRT 的 DLL 匯入程式庫。DLL import library for the Debug version of the UCRT. 不可轉散發。Not redistributable. /MDd _DEBUG, _MT, _DLL_DEBUG, _MT, _DLL

內含 Visual C++ CRT 實作特定程式碼的 vcruntime 程式庫,例如例外狀況處理和偵錯支援、執行階段檢查和類型資訊、實作詳細資料和特定擴充程式庫函式。The vcruntime library contains Visual C++ CRT implementation-specific code, such as exception handling and debugging support, runtime checks and type information, implementation details and certain extended library functions. 這個程式庫會因所使用的編譯器版本而有所不同。This library is specific to the version of the compiler used.

下表列出實作 vcruntime 程式庫的程式庫。This table lists the libraries that implement the vcruntime library.

程式庫Library 相關聯的 DLLAssociated DLL 特性Characteristics 選項Option 前置處理器指示詞Preprocessor directives
libvcruntime.lib None 以靜態方式連結到您的程式碼。Statically linked into your code. /MT _MT
libvcruntimed.lib None 用於靜態連結的偵錯版本。Debug version for static linking. 不可轉散發。Not redistributable. /MTd _MT, _DEBUG_MT, _DEBUG
vcruntime.lib vcruntime<version>.dll vcruntime 的 DLL 匯入程式庫。DLL import library for the vcruntime. /MD _MT, _DLL_MT, _DLL
vcruntimed.lib vcruntime<version>d.dll 偵錯 vcruntime 的 DLL 匯入程式庫。DLL import library for the Debug vcruntime. 不可轉散發。Not redistributable. /MDd _DEBUG, _MT, _DLL_DEBUG, _MT, _DLL

注意

發生 UCRT 重整時,會將並行執行階段函式移至,該函式 concrt140.dll 已新增至 c + + 可轉散發套件。When the UCRT refactoring occurred, the Concurrency Runtime functions were moved into concrt140.dll, which was added to the C++ redistributable package. C++ 平行容器和演算法 (例如 concurrency::parallel_for) 必須有這個 DLL。This DLL is required for C++ parallel containers and algorithms such as concurrency::parallel_for. 此外,C++ 標準程式庫也要求 Windows XP 上必須有這個 DLL,以支援同步基元,因為 Windows XP 並沒有條件變數。In addition, the C++ Standard Library requires this DLL on Windows XP to support synchronization primitives, because Windows XP does not have condition variables.

根據 CRT 程式庫為靜態或動態連結,為機器碼、Managed 程式碼或混合程式碼,初始化 CRT 的程式碼會位於上述幾個程式庫的其中一個。The code that initializes the CRT is in one of several libraries, based on whether the CRT library is statically or dynamically linked, or native, managed, or mixed code. 這段程式碼會處理 CRT 啟始、內部每個執行緒資料的初始化及終止。This code handles CRT startup, internal per-thread data initialization, and termination. 它會因所使用的編譯器版本而有所不同。It is specific to the version of the compiler used. 這個程式庫一律會以靜態方式連結,即使使用動態連結的 UCRT 亦然。This library is always statically linked, even when using a dynamically linked UCRT.

下表列出實作 CRT 初始化和終止的程式庫。This table lists the libraries that implement CRT initialization and termination.

程式庫Library 特性Characteristics 選項Option 前置處理器指示詞Preprocessor directives
libcmt.lib 以靜態方式將原生 UCRT 啟始連結到您的程式碼。Statically links the native CRT startup into your code. /MT _MT
libcmtd.lib 以靜態方式連結到偵錯版的原生 CRT 啟始。Statically links the Debug version of the native CRT startup. 不可轉散發。Not redistributable. /MTd _DEBUG, _MT_DEBUG, _MT
msvcrt.lib 搭配 DLL UCRT 和 vcruntime 使用之原生 CRT 啟始的靜態程式庫。Static library for the native CRT startup for use with DLL UCRT and vcruntime. /MD _MT, _DLL_MT, _DLL
msvcrtd.lib 搭配 DLL UCRT 和 vcruntime 使用之偵錯版原生 CRT 啟始的靜態程式庫。Static library for the Debug version of the native CRT startup for use with DLL UCRT and vcruntime. 不可轉散發。Not redistributable. /MDd _DEBUG, _MT, _DLL_DEBUG, _MT, _DLL
msvcmrt.lib 搭配 DLL UCRT 和 vcruntime 使用之混合原生與 Managed CRT 啟始的靜態程式庫。Static library for the mixed native and managed CRT startup for use with DLL UCRT and vcruntime. /clr
msvcmrtd.lib 搭配 DLL UCRT 和 vcruntime 使用之偵錯版混合原生與 Managed CRT 啟始的靜態程式庫。Static library for the Debug version of the mixed native and managed CRT startup for use with DLL UCRT and vcruntime. 不可轉散發。Not redistributable. /clr
msvcurt.lib 已被取代 純粹 Managed CRT 的靜態程式庫。Deprecated Static library for the pure managed CRT. /clr:pure
msvcurtd.lib 已被取代 偵錯版之純粹 Managed CRT 的靜態程式庫。Deprecated Static library for the Debug version of the pure managed CRT. 不可轉散發。Not redistributable. /clr:pure

如果您從命令列連結程式,而沒有指定 C 執行時間程式庫的編譯器選項,則連結器會使用靜態連結的 CRT 程式庫: libcmt.liblibvcruntime.liblibucrt.libIf you link your program from the command line without a compiler option that specifies a C run-time library, the linker will use the statically linked CRT libraries: libcmt.lib, libvcruntime.lib, and libucrt.lib.

使用靜態連結的 CRT 表示 C 執行階段程式庫所儲存的任何狀態資訊,都會是 CRT 執行個體的本機資訊。Using the statically linked CRT implies that any state information saved by the C runtime library will be local to that instance of the CRT. 例如,如果您在 strtok 使用靜態連結的 CRT 時使用,剖析器的位置與 strtok 相同進程中程式 strtok 代碼所使用的狀態無關 (但在連結至另一個靜態 CRT 實例的不同 DLL 或 EXE) 中。For example, if you use strtok when using a statically linked CRT, the position of the strtok parser is unrelated to the strtok state used in code in the same process (but in a different DLL or EXE) that is linked to another instance of the static CRT. 反之,動態連結的 CRT 在動態連結到該 CRT 之處理序中,會共用所有程式碼的狀態。In contrast, the dynamically linked CRT shares state for all code within a process that is dynamically linked to the CRT. 如果您使用更安全的新函式版本,就無須考慮此問題。例如 strtok_s 就沒有此問題。This concern does not apply if you use the new more secure versions of these functions; for example, strtok_s does not have this problem.

因為藉由連結到靜態 CRT 所建置的 DLL,會具備自己的 CRT 狀態,因此除非您已確實了解此結果並有此需要,否則不建議在 DLL 中以靜態方式連結到 CRT。Because a DLL built by linking to a static CRT will have its own CRT state, it is not recommended to link statically to the CRT in a DLL unless the consequences of this are specifically desired and understood. 例如,如果您 _set_se_translator 在載入連結到其自有靜態 CRT 之 dll 的可執行檔中呼叫,轉譯器將不會捕捉到 dll 中的程式碼所產生的任何硬體例外狀況,但是會攔截到主要可執行檔中的程式碼所產生的硬體例外狀況。For example, if you call _set_se_translator in an executable that loads the DLL linked to its own static CRT, any hardware exceptions generated by the code in the DLL will not be caught by the translator, but hardware exceptions generated by code in the main executable will be caught.

如果您使用 /clr 編譯器參數,您的程式碼將會與靜態程式庫(msvcurt.lib)連結。If you are using the /clr compiler switch, your code will be linked with a static library, msvcmrt.lib. 靜態程式庫會提供 Managed 程式碼與原生 CRT 之間的 Proxy。The static library provides a proxy between your managed code and the native CRT. 您無法使用靜態連結的 CRT ( /MT/MTd) 的選項 /clrYou cannot use the statically linked CRT ( /MT or /MTd options) with /clr. 請改用動態連結的程式庫 (/MD/MDd) 。Use the dynamically-linked libraries (/MD or /MDd) instead. 純粹受控 CRT 程式庫在 Visual Studio 2015 中已被取代,而在 Visual Studio 2017 中已不受支援。The pure managed CRT libraries are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.

如需搭配使用 CRT 的詳細資訊 /clr ,請參閱 混合 (原生和 Managed) 元件For more information on using the CRT with /clr, see Mixed (Native and Managed) Assemblies.

若要建立應用程式的偵錯工具, _DEBUG 必須定義旗標,且應用程式必須與其中一個程式庫的 debug 版本連結。To build a debug version of your application, the _DEBUG flag must be defined and the application must be linked with a debug version of one of these libraries. 如需如何使用程式庫檔案之偵錯版本的詳細資訊,請參閱 CRT 偵錯技術For more information about using the debug versions of the library files, see CRT Debugging Techniques.

本版 CRT 不完全符合 C99 標準。This version of the CRT is not fully conformant with the C99 standard. 在 Visual Studio 2019 16.8 版之前的版本中, <tgmath.h> 不支援此標頭。In versions before Visual Studio 2019 version 16.8, the <tgmath.h> header is not supported. 在所有版本中, CX_LIMITED_RANGE FP_CONTRACT 都不支援和 pragma 宏。In all versions, the CX_LIMITED_RANGE and FP_CONTRACT pragma macros are not supported. 像是標準 IO 函式的參數規範意義等特定項目,預設會使用舊版解譯。Certain elements such as the meaning of parameter specifiers in standard IO functions use legacy interpretations by default. 您可以使用 /Zc 編譯器一致性選項,並指定連結器選項來控制程式庫符合性的某些層面。You can use /Zc compiler conformance options and specify linker options to control some aspects of library conformance.

C++ 標準程式庫C++ Standard Library

C++ 標準程式庫C++ Standard Library 特性Characteristics 選項Option 前置處理器指示詞Preprocessor directives
libcpmt.lib 多執行緒、靜態連結Multithreaded, static link /MT _MT
msvcprt.lib 多執行緒、動態連結 () 的匯入程式庫 msvcp<version>.dllMultithreaded, dynamic link (import library for msvcp<version>.dll) /MD _MT, _DLL_MT, _DLL
libcpmtd.lib 多執行緒、靜態連結Multithreaded, static link /MTd _DEBUG, _MT_DEBUG, _MT
msvcprtd.lib 多執行緒、動態連結 () 的匯入程式庫 msvcp<version>d.dllMultithreaded, dynamic link (import library for msvcp<version>d.dll) /MDd _DEBUG, _MT, _DLL_DEBUG, _MT, _DLL

當您建立專案的發行版本時,其中一個基本 C 執行時間程式庫 (libcmt.libmsvcmrt.lib msvcrt.lib) 預設是連結的,這取決於您選擇的編譯器選項 (多執行緒、DLL /clr) 。When you build a release version of your project, one of the basic C run-time libraries (libcmt.lib, msvcmrt.lib, msvcrt.lib) is linked by default, depending on the compiler option you choose (multithreaded, DLL, /clr). 如果您在程式碼中包含其中一個 C++ 標準程式庫標頭檔,Visual C++ 就會在編譯時間自動連入 C++ 標準程式庫。If you include one of the C++ Standard Library header files in your code, a C++ Standard Library will be linked in automatically by Visual C++ at compile time. 例如:For example:

#include <ios>

為了要能夠和二進位碼相容,單一匯入程式庫會指定多個 DLL 檔案。For binary compatibility, more than one DLL file may be specified by a single import library. 版本更新會導入 dot 程式庫,其為其他引入新程式庫功能的 Dll。Version updates may introduce dot libraries, separate DLLs that introduce new library functionality. 例如,Visual Studio 2017 15.6 版引進, msvcp140_1.dll 以支援額外的標準程式庫功能,而不會中斷所支援的 ABI msvcp140.dllFor example, Visual Studio 2017 version 15.6 introduced msvcp140_1.dll to support additional standard library functionality without breaking the ABI supported by msvcp140.dll. msvcprt.lib Visual Studio 2017 15.6 版的工具組中包含的匯入程式庫同時支援這兩個 dll,而此版本的 vcredist 會安裝這兩個 dll。The msvcprt.lib import library included in the toolset for Visual Studio 2017 version 15.6 supports both DLLs, and the vcredist for this version installs both DLLs. 送出後,dot 程式庫即會有固定的 ABI,且絕對不會相依於更新版的程式庫。Once shipped, a dot library has a fixed ABI, and will never have a dependency on a later dot library.

如果應用程式使用多種 CRT 版本,將會發生什麼問題?What problems exist if an application uses more than one CRT version?

每個可執行映像 (EXE 或 DLL) 都可擁有自己的靜態連結 CRT,或者也可以動態連結至 CRT。Every executable image (EXE or DLL) can have its own statically linked CRT, or can dynamically link to a CRT. 靜態包含或由特定映像動態載入的 CRT 版本,取決於建置所用工具和資料庫的版本。The version of the CRT statically included in or dynamically loaded by a particular image depends on the version of the tools and libraries it was built with. 單一處理序可能會載入多個 EXE 和 DLL 映像,而每個都有自己的 CRT。A single process may load multiple EXE and DLL images, each with its own CRT. 這些 CRT 可能使用不同的配置器、可能具有不同的內部結構配置,且可能使用不同的存放安排。Each of those CRTs may use a different allocator, may have different internal structure layouts, and may use different storage arrangements. 這表示跨 DLL 界限的配置記憶體、CRT 資源或類別,可能會造成記憶體管理、內部靜態變數使用或配置解譯上的錯誤。This means that allocated memory, CRT resources, or classes passed across a DLL boundary can cause problems in memory management, internal static usage, or layout interpretation. 例如,如果有一個類別配置在某個 DLL 中,但是被傳遞到另一個 DLL 並且被刪除,則會使用哪一個 CRT 釋放器?For example, if a class is allocated in one DLL but passed to and deleted by another, which CRT deallocator is used? 這種情況可能會造成從輕微至嚴重的錯誤,因此強烈不建議移轉這類資源。The errors caused can range from the subtle to the immediately fatal, and therefore direct transfer of such resources is strongly discouraged.

若要避免許多這類問題,可以改用應用程式二進位介面 (ABI) 技術,因為這些技術較為穩定且可設定版本。You can avoid many of these issues by using Application Binary Interface (ABI) technologies instead, as they are designed to be stable and versionable. 將您的 DLL 匯出介面設計成以值傳遞資訊,或是使用呼叫者傳入的記憶體,而不是在區域中配置後再傳回給呼叫者。Design your DLL export interfaces to pass information by value, or to work on memory that is passed in by the caller rather than allocated locally and returned to the caller. 使用封送處理技術,在可執行檔映射之間複製結構化資料。Use marshaling techniques to copy structured data between executable images. 在區域中封裝資源,並且只允許透過您公開給用戶端的控制代碼或函式來進行操作。Encapsulate resources locally and only allow manipulation through handles or functions you expose to clients.

如果處理序中的所有映像都使用 CRT 的相同動態載入版本,則也可能避開部分這類問題。It's also possible to avoid some of these issues if all of the images in your process use the same dynamically loaded version of the CRT. 若要確保所有元件都使用相同的 CRT DLL 版本,請使用選項來建立它們, /MD 然後使用相同的編譯器工具組和屬性設定。To ensure that all components use the same DLL version of the CRT, build them by using the /MD option, and use the same compiler toolset and property settings.

如果您的程式會跨 DLL 界限傳遞某些 CRT 資源,請務必小心。Be careful if your program passes certain CRT resources across DLL boundaries. 檔案控制代碼、地區設定和環境變數等資源可能會造成問題,即使使用相同版本的 CRT 也是一樣。Resources such as file handles, locales, and environment variables can cause problems, even when using the same version of the CRT. 如需涉及問題及解決方法的相關資訊,請參閱跨 DLL 界限傳遞 CRT 物件時可能發生的錯誤For more information on the issues involved and how to resolve them, see Potential Errors Passing CRT Objects Across DLL Boundaries.

另請參閱See also