C 執行時間 (CRT) 和 C++ 標準程式庫 (STL) .lib 檔案

本文列出當您開發應用程式時可以連結的 Microsoft C 執行時間程式庫 .lib 檔案,以及其相關聯的編譯器選項和預處理器指示詞。

如果您想要部署支援應用程式所需的 C 執行時間檔案相關資訊,請參閱 轉散發 Visual C++ 檔案

如果您要尋找 C 執行時間程式庫的 API 參考,請參閱 C 執行時間程式庫參考

注意

Microsoft 的 C++ 標準程式庫實作通常稱為 STL 標準範本程式庫 。 雖然 C++ 標準程式庫是 ISO 14882 中所定義的程式庫 正式名稱,但由於搜尋引擎中常用的 「STL」 和 「Standard Template Library」 ,我們偶爾會使用這些名稱來更輕鬆地尋找我們的檔。

從歷史觀點來看,「STL」最初提到亞歷山大·斯蒂芬諾夫撰寫的標準範本庫。 該程式庫的部分已在 C++ 標準程式庫中標準化。 標準程式庫也會納入 ISO C 執行時間程式庫、Boost 程式庫的一部分,以及其他功能。 有時候會使用 「STL」 來參考從 Stepanov 的 STL 改編的 C++ 標準程式庫容器和演算法部分。 在本檔中,標準範本程式庫 (STL) 會整體參考 C++ 標準程式庫。

C 執行時間 .lib 檔案

ISO C 標準程式庫是 C++ 標準程式庫的一部分。 實作 CRT 的 Visual C++ 程式庫支援機器碼開發,以及混合的機器碼與受控碼。 CRT 的所有版本都支援多執行緒開發。 大部分程式庫都支援靜態連結和動態連結,靜態連結可將程式庫直接連結到您的程式碼,而動態連結則可讓您的程式碼使用通用 DLL 檔案。

在 Visual Studio 2015 中,CRT 已重構為新的二進位檔。 通用 CRT (UCRT) 包含標準 C99 CRT 程式庫所匯出的函式和全域變數。 UCRT 現在是 Windows 元件,並隨附于 Windows 10 和更新版本。 UCRT 的靜態程式庫、DLL 匯入程式庫和標頭檔現在可在 Windows SDK 中找到。 當您安裝 Visual C++ 時,Visual Studio 安裝程式會安裝使用 UCRT 所需的 Windows SDK 子集。 您可以在 Visual Studio 2015 及以上版本支援的任何 Windows 版本上使用 UCRT。 您可以針對 Windows 10 或更新版本以外的支援 Windows 版本,使用 vcredist 來轉散發它。 如需詳細資訊,請參閱轉散發 Visual C++ 檔案

下表列出實作 UCRT 的程式庫。

程式庫 相關聯的 DLL 特性 選項 前置處理器指示詞
libucrt.lib 以靜態方式將 UCRT 連結到您的程式碼。 /MT _MT
libucrtd.lib 用於靜態連結的偵錯版 UCRT。 不可轉散發。 /MTd _DEBUG, _MT
ucrt.lib ucrtbase.dll UCRT 的 DLL 匯入程式庫。 /MD _MT, _DLL
ucrtd.lib ucrtbased.dll 偵錯版 UCRT 的 DLL 匯入程式庫。 不可轉散發。 /MDd _DEBUG, _MT, _DLL

vcruntime 程式庫包含 Visual C++ CRT 實作特定程式碼:例外狀況處理和偵錯支援、執行時間檢查和類型資訊、實作詳細資料,以及特定擴充程式庫函式。 vcruntime 程式庫版本必須符合您使用的編譯器版本。

下表列出實作 vcruntime 程式庫的程式庫。

程式庫 相關聯的 DLL 特性 選項 前置處理器指示詞
libvcruntime.lib 以靜態方式連結到您的程式碼。 /MT _MT
libvcruntimed.lib 用於靜態連結的偵錯版本。 不可轉散發。 /MTd _MT, _DEBUG
vcruntime.lib vcruntime<version>.dll vcruntime 的 DLL 匯入程式庫。 /MD _MT, _DLL
vcruntimed.lib vcruntime<version>d.dll 偵錯 vcruntime 的 DLL 匯入程式庫。 不可轉散發。 /MDd _DEBUG, _MT, _DLL

注意

重構 UCRT 時,並行執行時間函式會移至 concrt140.dll ,並新增至 C++ 可轉散發套件。 C++ 平行容器和演算法 (例如 concurrency::parallel_for) 必須有這個 DLL。 此外,C++ 標準程式庫需要 Windows XP 上的這個 DLL 來支援同步處理基本類型,因為 Windows XP 沒有條件變數。

根據 CRT 程式庫為靜態或動態連結,為機器碼、Managed 程式碼或混合程式碼,初始化 CRT 的程式碼會位於上述幾個程式庫的其中一個。 這段程式碼會處理 CRT 啟始、內部每個執行緒資料的初始化及終止。 其專屬於所使用的編譯器版本。 這個程式庫一律會以靜態方式連結,即使使用動態連結的 UCRT 亦然。

下表列出實作 CRT 初始化和終止的程式庫。

程式庫 特性 選項 前置處理器指示詞
libcmt.lib 以靜態方式將原生 UCRT 啟始連結到您的程式碼。 /MT _MT
libcmtd.lib 以靜態方式連結到偵錯版的原生 CRT 啟始。 不可轉散發。 /MTd _DEBUG, _MT
msvcrt.lib 搭配 DLL UCRT 和 vcruntime 使用之原生 CRT 啟始的靜態程式庫。 /MD _MT, _DLL
msvcrtd.lib 搭配 DLL UCRT 和 vcruntime 使用之偵錯版原生 CRT 啟始的靜態程式庫。 不可轉散發。 /MDd _DEBUG, _MT, _DLL
msvcmrt.lib 搭配 DLL UCRT 和 vcruntime 使用之混合原生與 Managed CRT 啟始的靜態程式庫。 /clr
msvcmrtd.lib 搭配 DLL UCRT 和 vcruntime 使用之偵錯版混合原生與 Managed CRT 啟始的靜態程式庫。 不可轉散發。 /clr
msvcurt.lib 已被取代 純粹 Managed CRT 的靜態程式庫。 /clr:pure
msvcurtd.lib 已被取代 偵錯版之純粹 Managed CRT 的靜態程式庫。 不可轉散發。 /clr:pure

如果您從命令列連結程式,而沒有指定 C 執行時間程式庫的編譯器選項,連結器會使用靜態連結的 CRT 程式庫: libcmt.liblibvcruntime.liblibucrt.lib

使用靜態連結的 CRT 表示 C 執行階段程式庫所儲存的任何狀態資訊,都會是 CRT 執行個體的本機資訊。 例如,如果您在使用靜態連結的 CRT 時使用 strtok ,剖析器的位置 strtok 與相同進程中程式碼中使用的狀態無關 strtok (但在不同的 DLL 或 EXE 中),而該狀態會連結到靜態 CRT 的另一個實例。 反之,動態連結的 CRT 在動態連結到該 CRT 之處理序中,會共用所有程式碼的狀態。 如果您使用這些函式的新更安全版本,則不適用此考慮;例如, strtok_s 沒有這個問題。

由於連結至靜態 CRT 所建置的 DLL 具有自己的 CRT 狀態,因此,除非瞭解並想要後果,否則不建議您將靜態連結至 DLL 中的 CRT。 例如,如果您在載入連結至自己靜態 CRT 之 DLL 的可執行檔中呼叫 _set_se_translator ,則譯者不會攔截 DLL 中程式碼所產生的任何硬體例外狀況,但主要可執行檔中程式碼所產生的硬體例外狀況將會攔截。

如果您使用編譯 /clr 程式參數,您的程式碼將會連結至靜態程式庫 。 msvcmrt.lib 靜態程式庫會提供 Managed 程式碼與原生 CRT 之間的 Proxy。 您無法搭配 使用靜態連結的 CRT ( /MT/MTd 選項)。 /clr 請改用動態連結的程式庫 ( /MD/MDd )。 純粹受控 CRT 程式庫在 Visual Studio 2015 中已被取代,而在 Visual Studio 2017 中已不受支援。

如需搭配 使用 CRT 的詳細資訊 /clr ,請參閱 混合式 (原生和 Managed) 元件

若要建置應用程式的偵錯版本,必須定義 旗標, _DEBUG 而且應用程式必須連結至其中一個程式庫的偵錯版本。 如需使用程式庫檔案偵錯版本的詳細資訊,請參閱 CRT 偵錯技術

此版本的 CRT 不符合 C99 標準。 在 Visual Studio 2019 16.8 版之前的版本中, <tgmath.h> 不支援 標頭。 在所有版本中, CX_LIMITED_RANGE 不支援 和 FP_CONTRACT pragma 宏。 像是標準 IO 函式的參數規範意義等特定項目,預設會使用舊版解譯。 您可以使用 /Zc 編譯器一致性選項,並指定連結器選項來控制程式庫一致性的某些層面。

C++ 標準程式庫 (STL) .lib 檔案

C++ 標準程式庫 特性 選項 前置處理器指示詞
libcpmt.lib 多執行緒、靜態連結 /MT _MT
msvcprt.lib 多執行緒動態連結 (的匯入 msvcp<version>.dll 程式庫) /MD _MT, _DLL
libcpmtd.lib 多執行緒、靜態連結 /MTd _DEBUG, _MT
msvcprtd.lib 多執行緒動態連結 (的匯入 msvcp<version>d.dll 程式庫) /MDd _DEBUG, _MT, _DLL

當您建置專案的發行版本本時,預設會連結其中一個基本 C 執行時間程式庫 (、 msvcmrt.libmsvcrt.lib 、 ) ,視您選擇的編譯器選項而定 libcmt.lib (多執行緒、DLL、 /clr )。 如果您在程式碼中包含其中 一個 C++ 標準程式庫標頭檔 ,在編譯時期,Visual C++ 會自動連結 C++ 標準程式庫。 例如:

#include <ios>

為了要能夠和二進位碼相容,單一匯入程式庫會指定多個 DLL 檔案。 版本更新會導入 dot 程式庫,其為其他引入新程式庫功能的 Dll。 例如,Visual Studio 2017 15.6 版引進 msvcp140_1.dll 來支援更標準的程式庫功能,而不需要中斷 所 msvcp140.dll 支援的應用程式二進位介面 (ABI)。 msvcprt.libVisual Studio 2017 15.6 版工具組中所包含的匯入程式庫同時支援 DLL,而此版本的 vcredist 會安裝這兩個 DLL。 送出後,dot 程式庫即會有固定的 ABI,且絕對不會相依於更新版的程式庫。

如果應用程式使用多種 CRT 版本,將會發生什麼問題?

每個可執行映像 (EXE 或 DLL) 都可擁有自己的靜態連結 CRT,或者也可以動態連結至 CRT。 靜態包含或由特定映像動態載入的 CRT 版本,取決於建置所用工具和資料庫的版本。 單一處理序可能會載入多個 EXE 和 DLL 映像,而每個都有自己的 CRT。 這些 CRT 可能使用不同的配置器、可能具有不同的內部結構配置,且可能使用不同的存放安排。 這表示跨 DLL 界限傳遞的已配置記憶體、CRT 資源或類別可能會導致記憶體管理、內部靜態使用量或配置解譯發生問題。 例如,如果有一個類別配置在某個 DLL 中,但是被傳遞到另一個 DLL 並且被刪除,則會使用哪一個 CRT 釋放器? 造成的錯誤可能從微妙到立即致命,因此不建議直接轉移這類資源。

您可以改用應用程式二進位介面 (ABI) 技術來避免這些問題,因為它們的設計是穩定且可建立版本。 將您的 DLL 匯出介面設計成以值傳遞資訊,或是使用呼叫者傳入的記憶體,而不是在區域中配置後再傳回給呼叫者。 使用封送處理技術在可執行映射之間複製結構化資料。 在區域中封裝資源,並且只允許透過您公開給用戶端的控制代碼或函式來進行操作。

如果處理序中的所有映像都使用 CRT 的相同動態載入版本,則也可能避開部分這類問題。 若要確保所有元件都使用相同的 CRT DLL 版本,請使用 /MD 選項來建置它們,並使用相同的編譯器工具組和屬性設定。

如果您的程式跨 DLL 界限傳遞特定 CRT 資源,請小心。 檔案控制代碼、地區設定和環境變數等資源可能會造成問題,即使使用相同的 CRT 版本也一樣。 如需有關問題以及如何解決這些問題的詳細資訊,請參閱 跨 DLL 界限 傳遞 CRT 物件的潛在錯誤。

另請參閱

C 執行時間程式庫參考
轉散發 Visual C++ 檔案