C ランタイム (CRT) と C++ 標準ライブラリ (STL) .lib ファイル

このトピックでは、アプリケーションの開発時にリンクできる Microsoft C ランタイムライブラリ .lib ファイルと、関連するコンパイラオプションとプリプロセッサディレクティブについて説明します。

アプリケーションをサポートするために必要な C ランタイムファイルの配置については、「 Visual C++ ファイル の再配布」を参照してください。

C ランタイムライブラリの API リファレンスについては、「 c ランタイムライブラリリファレンス 」を参照してください。

C ランタイム .lib ファイル

C ランタイムライブラリ (CRT) は、ISO C 標準ライブラリが組み込まれている C++ 標準ライブラリの一部です。 この CRT を実装する Visual C++ ライブラリは、ネイティブ コードの開発と、ネイティブとマネージドの混在コードの開発をサポートします。 CRT のすべてのバージョンがマルチスレッド開発をサポートします。 ほとんどのライブラリが、ライブラリを直接コードにリンクする静的リンクと、コードで共通 DLL ファイルを使用できるようにする動的リンクの両方をサポートします。

Visual Studio 2015 より、CRT が新しいバイナリにリファクタリングされました。 ユニバーサル CRT (UCRT) には、標準の C99 CRT ライブラリからエクスポートされた関数とグローバルが含まれています。 UCRT は Windows コンポーネントであり、Windows 10 の一部として出荷されます。 UCRT 用のスタティック ライブラリ、DLL インポート ライブラリ、およびヘッダー ファイルが Windows 10 SDK に含まれています。 Visual C++ をインストールすると、Visual Studio セットアップによって、UCRT を使用するために必要な Windows 10 SDK のサブセットがインストールされます。 UCRT は、Visual Studio 2015 以降のバージョンでサポートされている Windows の任意のバージョンで使用できます。 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++ 再頒布可能パッケージに追加されたに移動されました。 この DLL は、C++ の並列コンテナーおよびアルゴリズム (concurrency::parallel_for など) に必要となります。 また、Windows XP には条件変数がないため、C++ 標準ライブラリでは同期プリミティブをサポートするためにこの DLL が必要です。

CRT を初期化するコードは、CRT ライブラリが静的にリンクされているのか、動的にリンクされているのか、ネイティブ コードなのか、マネージド コードなのか、混合コードなのかによって、複数あるライブラリのいずれかに含まれています。 このコードは、CRT のスタートアップ、内部スレッド単位データ初期化、および強制終了を処理します。 これは、使用するコンパイラのバージョンに固有です。 このライブラリは、動的にリンクされた UCRT が使用されている場合でも、常に静的にリンクされます。

次の表に、CRT の初期化と強制終了を実装するライブラリの一覧を示します。

ライブラリ 特性 オプション プリプロセッサ ディレクティブ
libcmt.lib ネイティブ CRT スタートアップをコードに静的にリンクします。 /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 で使用するためのネイティブとマネージドの混合 CRT スタートアップ用のスタティック ライブラリ。 /clr
msvcmrtd.lib DLL UCRT および vcruntime で使用するためのネイティブとマネージドの混合 CRT スタートアップのデバッグ バージョン用のスタティック ライブラリ。 再頒布可能パッケージではありません。 /clr
msvcurt.lib 非推奨 純粋マネージド CRT 用のスタティック ライブラリ。 /clr:pure
msvcurtd.lib 非推奨 純粋マネージド CRT のデバッグ バージョン用のスタティック ライブラリ。 再頒布可能パッケージではありません。 /clr:pure

C ランタイムライブラリを指定するコンパイラオプションを使用せずに、コマンドラインからプログラムをリンクした場合、リンカーは静的にリンクされた CRT ライブラリである、、およびを使用します libcmt.lib libvcruntime.lib libucrt.lib

静的にリンクされた CRT を使用すると、暗黙的に、C ランタイム ライブラリによって保存されるステータス情報は CRT のそのインスタンスに対してローカルなものになります。 たとえば、静的にリンクされた CRT を使用する場合、 strtok パーサーの位置 strtok は、 strtok 静的な crt の別のインスタンスにリンクされている同じプロセス (ただし、別の DLL または EXE) のコードで使用される状態とは関係がありません。 反対に、動的にリンクされた CRT では、CRT に動的にリンクされるプロセス内のすべてのコードに対して状態が共有されます。 これらの関数のセキュリティが強化された新しいバージョンを使用する場合、この問題は適用されません。たとえば、には strtok_s この問題はありません。

静的な CRT へのリンクによってビルドされた DLL は独自の CRT 状態を持つため、このような結果が明確に特定され、理解されている場合を除き、DLL 内の CRT に静的にリンクすることはお勧めしません。 たとえば、 _set_se_translator 独自の静的 CRT にリンクされた dll を読み込む実行可能ファイルでを呼び出すと、dll 内のコードによって生成されたハードウェア例外はトランスレーターによって検出されませんが、メインの実行可能ファイルのコードによって生成されるハードウェア例外はキャッチされます。

コンパイラスイッチを使用している場合 /clr 、コードはスタティックライブラリ (msvcmrt.lib) にリンクされます。 このスタティック ライブラリは、マネージド コードとネイティブ CRT 間のプロキシを提供します。 静的にリンクされた CRT ( /MT または /MTd オプション) をと共に使用することはできません /clr 。 代わりに、動的にリンクされるライブラリ (または) を使用して /MD /MDd ください。 純粋マネージ CRT のライブラリは、Visual Studio 2015 で非推奨となり、Visual Studio 2017 ではサポートされていません。

で CRT を使用する方法の詳細につい /clr ては、「 Mixed (ネイティブおよびマネージ) アセンブリ」を参照してください。

アプリケーションのデバッグバージョンをビルドするには、 _DEBUG フラグを定義し、アプリケーションをこれらのライブラリのいずれかのデバッグバージョンにリンクする必要があります。 ライブラリ ファイルのデバッグ バージョンの使い方の詳細については、「 CRT のデバッグ技術」を参照してください。

このバージョンの CRT は、C99 標準に完全には準拠していません。 Visual Studio 2019 バージョン16.8 より前のバージョンでは、 <tgmath.h> ヘッダーはサポートされていません。 すべてのバージョンで、 CX_LIMITED_RANGE および FP_CONTRACT プラグママクロはサポートされていません。 標準 IO 関数内のパラメーター指定子の意味などの特定の要素で、既定で、従来の解釈が使用されます。 /Zc コンパイラ準拠オプションを使用して、リンカーオプションを指定して、ライブラリ準拠の一部の側面を制御できます。

C++ 標準ライブラリ .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

プロジェクトのリリースバージョンをビルドすると、 libcmt.lib msvcmrt.lib 選択し msvcrt.lib たコンパイラオプション (マルチスレッド、DLL、) に応じて、基本的な C ランタイムライブラリ (、、) のいずれかが既定でリンクされ /clr ます。 コードに C++ 標準ライブラリのヘッダーファイル の1つを含めると、コンパイル時に Visual C++ によって C++ 標準ライブラリが自動的にリンクされます。 次に例を示します。

#include <ios>

バイナリの互換性のため、複数の DLL ファイルが 1 つのインポート ライブラリによって指定される場合があります。 バージョンの更新によって、ドット ライブラリ が導入される場合があります。これは、新しいライブラリ機能が導入される別の DLL です。 たとえば、 msvcp140_1.dll によってサポートされるアプリケーションバイナリインターフェイス (ABI) を壊さずに、追加の標準ライブラリ機能をサポートするために Visual Studio 2017 バージョン15.6 が導入されました msvcp140.dllmsvcprt.lib Visual Studio 2017 バージョン15.6 のツールセットに含まれるインポートライブラリは両方の dll をサポートし、このバージョンの vcredist は両方の dll をインストールします。 出荷後は、ドット ライブラリに修正された ABI が含まれ、以後のドット ライブラリに対する依存関係はなくなります。

アプリケーションで複数の CRT バージョンを使用した場合に発生する問題

すべての実行可能イメージ (EXE または DLL) は、静的にリンクされた独自の CRT を持たせるか、動的に CRT にリンクさせることができます。 特定のイメージによって静的に含まれる、または動的に読み込まれる CRT のバージョンは、ビルド時に使用されたツールとライブラリのバージョンによって異なります。 1 つのプロセスが複数の EXE や DLL イメージを読み込み、そのそれぞれが独自の CRT を持っている場合があります。 これらの各 CRT は、異なる allocator を使用し、異なる内部構造体のレイアウトを備え、異なるストレージ配置を使用する可能性があります。 つまり、割り当てられたメモリ、CRT リソース、または DLL の境界を越えて渡されるクラスによって、メモリ管理、内部の静的な使用、またはレイアウトの解釈で問題が発生する可能性があります。 たとえば、1 つの DLL に割り当てられているクラスが別の DLL に渡されて削除された場合、使用されるのはどの CRT の deallocator でしょうか。 発生するエラーは微妙なものから即座に致命的となるものまでさまざまです。そのため、そのようなリソースを直接転送することは、回避することを強くお勧めします。

代わりに、アプリケーション バイナリ インターフェイス (ABI) テクノロジを使用することで、この問題の多くを回避できます。安定しバージョン管理が可能であるように設計されるためです。 値によって情報を渡すか、ローカルで割り当てたメモリを呼び出し元に返すのではなく呼び出し元によって渡されたメモリを使用するように、DLL のエクスポート インターフェイスを設計します。 実行可能イメージ間で構造化データをコピーするには、マーシャリング技法を使用します。 リソースをローカルでカプセル化し、クライアントに公開したハンドルまたは関数を通してのみこれを操作できるようにします。

また、プロセス内のすべてのイメージで同じバージョンの CRT が動的に読み込まれる場合は、これらの問題を一部回避することもできます。 すべてのコンポーネントが同じ DLL バージョンの CRT を使用するようにするには、オプションを使用してビルド /MD し、同じコンパイラツールセットとプロパティ設定を使用します。

プログラムが DLL の境界を越えて特定の CRT リソースを渡す場合は注意してください。 ファイルハンドル、ロケール、環境変数などのリソースでは、同じバージョンの CRT を使用している場合でも、問題が発生する可能性があります。 発生する可能性のある問題とその対処法の詳細については、「DLL の境界を越えて CRT オブジェクトを渡す場合に発生する可能性のあるエラー」を参照してください。

関連項目