CRT ライブラリの機能
ここでは、C ランタイム ライブラリを構成するさまざまな .lib ファイル、および関連するコンパイラ オプションとプリプロセッサ ディレクティブについて説明します。
C ランタイム ライブラリ (CRT)
次の表のライブラリには、C ランタイム ライブラリ関数が含まれています。
C ランタイム ライブラリ (iostream ライブラリと標準 C++ ライブラリを除く) |
関連付けられている DLL |
特性 |
オプション |
プリプロセッサ ディレクティブ |
---|---|---|---|---|
libcmt.lib |
なし、静的リンク |
マルチスレッド、静的リンク |
_MT |
|
msvcrt.lib |
msvcr110.dll |
マルチスレッド、動的リンク (MSVCR110.DLL 用インポート ライブラリ)。標準 C++ ライブラリを使用する場合、プログラムの実行には MSVCP110.DLL が必要です。 |
_MT、_DLL |
|
libcmtd.lib |
なし、静的リンク |
マルチスレッド、静的リンク (デバッグ) |
/MTd |
_DEBUG、_MT |
msvcrtd.lib |
msvcr110d.dll |
マルチスレッド、動的リンク (MSVCR110D.DLL 用インポート ライブラリ) (デバッグ) |
/MDd |
_DEBUG、_MT、_DLL |
msvcmrt.lib |
なし、静的リンク |
C のランタイム静的ライブラリです。マネージ コードとネイティブ コードの混合コードに対して使用します。 |
/clr /clr:oldSyntax |
|
msvcurt.lib |
なし、静的リンク |
100% 純粋な MSIL コードとしてコンパイルされた C ランタイム静的ライブラリです。すべてのコードが MSIL 対応の ECMA URT 仕様に準拠します。 |
/clr:pure |
|
[!メモ]
シングルスレッド CRT (libc.lib、libcd.lib) (以前の /ML オプションまたは /MLd オプション) は使用されなくなりました。代わりに、マルチスレッド CRT を使用します。マルチスレッド ライブラリのパフォーマンス を参照してください。
C ランタイム ライブラリを指定するコンパイラ オプションを使用せずにコマンド ラインからプログラムをリンクした場合、リンカーは LIBCMT.LIB を使用します。これは、以前のバージョンの Visual C++ とは異なります。以前のバージョンでは、シングルスレッド ライブラリである LIBC.LIB が使用されました。
静的にリンクされた CRT を使用すると、暗黙的に、C ランタイム ライブラリによって保存されるステータス情報は CRT のそのインスタンスに対してローカルなものになります。たとえば、静的にリンクされた CRT を使用している状態で strtok、_strtok_l、wcstok、_wcstok_l、_mbstok、_mbstok_l を使用した場合、strtok パーサーの位置は、静的な CRT の別のインスタンスにリンクされた同じプロセス内 (ただし DLL または EXE は別) のコードで使用される strtok の状態とは無関係になります。反対に、動的にリンクされた CRT では、CRT に動的にリンクされるプロセス内のすべてのコードに対して状態が共有されます。この問題は、セキュリティが強化された新しいバージョンの関数では発生しません。たとえば、strtok_s にはこの問題はありません。
静的な CRT とのリンクによってビルドされた DLL は独自の CRT 状態を持つので、この結果を明確に理解し、期待する場合を除き、DLL 内で CRT に静的にリンクすることは推奨されません。たとえば、独自の静的な CRT にリンクする DLL を読み込む実行可能ファイルで _set_se_translator を呼び出すと、このトランスレータは DLL 内のコードで生成されたハードウェア例外をキャッチしませんが、メインの実行可能ファイル内のコードによって生成されたハードウェア例外をキャッチします。
/clr コンパイラ スイッチを使用すると、コードはスタティック ライブラリ msvcmrt.lib とリンクされます。このスタティック ライブラリは、マネージ コードとネイティブ CRT 間のプロキシを提供します。/clr は、静的にリンクされる CRT (/MT オプションまたは /MTd オプション) と一緒には使用できません。代わりに、動的にリンクされるライブラリ (/MD または /MDd) を使用してください。
使用している場合は、 /clr:pureコンパイラ スイッチは、コード、静的ライブラリ msvcurt.lib にリンクされます。/clr と同様、静的にリンクされるライブラリにはリンクできません。
/clr と共に CRT を使用する方法の詳細については、「混在 (ネイティブおよびマネージ) アセンブリ」を参照してください。/clr:pure については、「純粋なコードと検証可能なコード (C++/CLI)」を参照してください。
アプリケーションのデバッグ バージョンをビルドするには、_DEBUG フラグが定義され、アプリケーションが上の表のいずれかのライブラリのデバッグ バージョンとリンクされている必要があります。ライブラリ ファイルのデバッグ バージョンの使い方の詳細については、「CRT のデバッグ技術」を参照してください。
このバージョンの Visual C++ は、C99 標準に準拠していません。
標準 C++ ライブラリ
標準 C++ ライブラリ |
特性 |
オプション |
プリプロセッサ ディレクティブ |
---|---|---|---|
LIBCPMT.LIB |
マルチスレッド、静的リンク |
/MT |
_MT |
MSVCPRT.LIB |
マルチ スレッド、動的リンク (MSVCP110.dll 用インポート ライブラリ) |
/MD |
_MT、_DLL |
LIBCPMTD.LIB |
マルチスレッド、静的リンク |
/MTd |
_DEBUG、_MT |
MSVCPRTD.LIB |
マルチスレッド、動的リンク (MSVCP110D.DLL 用インポート ライブラリ) |
/MDd |
_DEBUG、_MT、_DLL |
注 LIBCP。LIB と LIBCPD。LIB (を介して、古い**/MLと/MLdオプション) 削除されました。代わりに、/MT** オプションと /MTd オプションを使用して LIBCPMT.LIB と LIBCPMTD.LIB を使用してください。
プロジェクトのリリース バージョンをビルドすると、既定では、選択したコンパイラ オプション (マルチスレッド、DLL、/clr) に応じて、基本 C ランタイム ライブラリ (LIBCMT.LIB、LIBCMT.LIB、MSVCRT.LIB) の 1 つがリンクされます。コードにヘッダー ファイルの 1 つがインクルードされている場合は、コンパイル時に Visual C++ によって自動的に標準 C++ ライブラリがリンクされます。次に例を示します。
#include <ios>
Msvcrt.dll と msvcr110.dll の違いを教えてください。
msvcrt.dll は "known DLL"、つまり、Windows が所有および構築するシステム コンポーネントになりました。msvcrt.dll は、システム レベルのコンポーネントだけで使用されることを前提としています。
Msvcrt.dll と msvcr110.dll の両方のアプリケーションを使用する場合は、どのような問題をありますか。
Msvcrt.lib にリンクする必要があります、.lib または .obj ファイルがある場合はするには、Visual c の新しい msvcrt.lib を再コンパイルする必要はありません。.lib ファイルや .obj ファイルは、さまざまな CRT クラスや変数のサイズ、フィールド オフセット、またはメンバー関数名に依存している場合がありますが、それらはすべて互換性を保ったまま存続します。Msvcrt.lib を再リンクすると、EXE および DLL の最終的なイメージここで依存関係に msvcrt.dll の代わりに msvcr110.dll 必要があります。
複数の DLL または EXE がある場合は、異なるバージョンの Visual C++ を使用しているかどうかにかかわらず、複数の CRT が使用される可能性があります。たとえば、CRT を複数の DLL に静的にリンクした場合に同じ問題が発生します。この静的 CRT の問題が発生した場合は、/MD でコンパイルして CRT DLL を使用するという対処が一般的です。CRT DLL を msvcr110.dll に変更されていますが、アプリケーションは msvcrt.dll と他の人に msvcr110.dll へのリンクの一部のコンポーネントがあります。Msvcrt.dll と msvcr110.dll の境界を越えて CRT のリソース Dll を渡す場合は、Crt の不一致が原因で問題が発生して、Visual C でプロジェクトを再コンパイルする必要があります。
複数のバージョンの CRT を使用するプロジェクトでは、DLL の境界を超えて特定の CRT オブジェクト (ファイル ハンドル、ロケール、環境変数など) を渡す場合には注意を要します。発生する可能性のある問題とその対処法の詳細については、「DLL の境界を越えて CRT オブジェクトを渡す場合に発生する可能性のあるエラー」を参照してください。