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 上支援同步處理基本類型,因為 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.lib
、 libvcruntime.lib
和 libucrt.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.lib
msvcrt.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.lib
Visual 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 對象的潛在錯誤。