CRT でのグローバル状態

ユニバーサル C ランタイム (UCRT) の一部の関数は、グローバル状態を使用します。 たとえば、setlocale() はプログラム全体のロケールを設定します。これは、桁区切り記号、テキスト コード ページなどに影響します。

UCRT のグローバル状態は、アプリケーションと OS 間では共有されません。 たとえば、アプリケーションが setlocale() を呼び出す場合、C ランタイムを使用する OS コンポーネントのロケールや、その逆の方法には影響しません。

CRT 関数の OS 固有バージョン

UCRT では、グローバル状態を使用してやり取りする関数には、先頭に _o_ が付く "ツイン" 関数があります。 次に例を示します。

  • setlocale() アプリ固有のグローバル状態に影響します。
  • _o_setlocale() アプリではなく、すべての OS コンポーネントによって共有されるグローバル状態に影響します。

これらの "ツイン" 関数の唯一の違いは、グローバル CRT 状態の読み取り/書き込みを行うときに OS 固有のバージョン (つまり、_o_ で始まるバージョン) では、アプリのグローバル状態のコピーではなく、グローバル状態の OS コピーを使用することです。

これらの関数の OS 固有のバージョンは、ucrt.osmode.lib にあります。 たとえば、setlocale() の OS 固有バージョンは _o_setlocale() です

コンポーネントの CRT 状態をアプリの CRT 状態から分離するには、次の 2 つの方法があります。

  • コンパイラ オプション /MT (リリース) または /MTd (デバッグ) を使用して、コンポーネントを静的にリンクします。 詳細については、/MD、/MT、/LD に関する記事を参照してください。 静的リンクを使用すると、バイナリ サイズを大幅に増やすことができます。
  • Windows 10 バージョン 2004 以降の Windows バージョンでは、CRT に動的にリンクしますが、OS モードのエクスポート (o で始まる関数) を呼び出します。 OS モードのエクスポートを呼び出すには、前と同じように静的にリンクしますが、リンカー オプション /NODEFAULTLIB:libucrt.lib (リリース) または /NODEFAULTLIB:libucrtd.lib (デバッグ) を使用して静的 UCRT を無視します。 ucrt.osmode.lib をリンカー入力に追加します。 詳細については、「 /NODEFAULTLIB (ライブラリを無視する) 」を参照してください。

Note

ソース コードでは、_o_setlocale() ではなく、setlocale() を記述します。 ucrt.osmode.lib に対してリンクすると、リンカーは自動的に OS 固有の関数のバージョンに置き換えます。 つまり、setlocale()_o_setlocale() に置き換えられます。

ucrt.osmode.lib に対するリンクは、アプリ モードでのみ使用できる一部の UCRT 呼び出しを無効にします。 これらの関数を呼び出そうとすると、リンク エラーが発生します。

アプリと OS の分離によって影響を受けるグローバル状態

アプリと OS の状態を分離することによって影響を受けるグローバル状態には、次のものが含まれます。

関連項目

C ランタイム ライブラリ リファレンス