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

この記事では、アプリケーションの開発時にリンクできる Microsoft C ランタイム ライブラリ .lib ファイルと、関連するコンパイラ オプションとプリプロセッサ ディレクティブの一覧を示します。

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

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

Note

Microsoft による C++ 標準ライブラリの実装は、多くの場合、STL または標準テンプレート ライブラリ呼ばれます。 C++ 標準ライブラリは ISO 14882 で定義されているライブラリの正式な名前ですが、検索エンジンでは "STL" と "標準テンプレート ライブラリ" が一般的に使用されているため、これらの名前を使用してドキュメントを見つけやすくなります。

歴史的な観点から見ると、"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 のサブセットがインストールされます。 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

Note

UCRT がリファクタリングされたとき、同時実行ランタイムは concrt140.dll に移動されました。これは C++ 再頒布可能パッケージに含まれています。 この DLL は、C++ の並列コンテナーおよびアルゴリズム (concurrency::parallel_for など) に必要となります。 さらに、C++ 標準ライブラリでは、Windows XP には条件変数がないため、同期プリミティブをサポートするために Windows XP 上のこの 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.liblibvcruntime.liblibucrt.lib) を使用します。

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

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

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

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

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

この CRT のバージョンは、C99 標準に完全には準拠していません。 Visual Studio 2019 バージョン 16.8 より前のバージョンでは、<tgmath.h> ヘッダーはサポートされません。 すべてのバージョンで、CX_LIMITED_RANGE および FP_CONTRACT プラグマ マクロはサポートされていません。 標準 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

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

#include <ios>

バイナリの互換性のため、複数の DLL ファイルが 1 つのインポート ライブラリによって指定される場合があります。 バージョンの更新によって、ドット ライブラリが導入される場合があります。これは、新しいライブラリ機能が導入される別の DLL です。 たとえば、Visual Studio 2017 バージョン 15.6 では、サポートされているアプリケーション バイナリ インターフェイス (ABI) を中断することなく、より多くの標準ライブラリ機能をサポートするために導入 msvcp140_1.dll されました msvcp140.dll。 Visual Studio 2017 バージョン 15.6 のツールセットに含まれる msvcprt.lib インポート ライブラリは両方の 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 が動的に読み込まれる場合は、これらの問題を一部回避することもできます。 すべてのコンポーネントで CRT の同じ DLL バージョンを使用するには、/MD オプションを指定してビルドし、同じコンパイラ ツールセットとプロパティ設定を使用します。

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

関連項目

C ランタイム ライブラリ リファレンス
Visual C++ ファイルの再配布