次の方法で共有


/kernel (カーネル モード バイナリの作成)

Windows カーネルで実行できるバイナリを作成します。 現在のプロジェクト内のコードは、カーネル モードで実行されるコードに固有の C++ 言語機能の、簡略化されたセットを使用してコンパイルおよびリンクされます。

構文

/kernel

解説

/kernel オプションを指定すると、どの言語機能がカーネル モードで許容されるかを判別し、カーネル モードの C++ に固有のランタイムの不安定性を回避するのに十分な表現力を持たせるように、コンパイラとリンカーに指示が送られます。 これは、カーネル モードで混乱を発生させる C++ 言語機能の使用を禁止することによって実施されます。 コンパイラは、混乱を発生させる可能性があるものの、無効にはできない可能性がある C++ 言語機能に対して警告を生成します。

/kernel オプションは、ビルドのコンパイラ フェーズとリンカー フェーズの両方に適用され、プロジェクト レベルで設定されます。 /kernel スイッチを渡すことで、リンク後の結果のバイナリを Windows カーネルに読み込む必要があることを、コンパイラに示すことができます。 コンパイラは、C++ 言語機能の範囲を、カーネルとの互換性があるサブセットに絞り込むことになります。

次の表は、/kernel を指定した場合にコンパイラの動作がどのように変わるかを示したものです。

動作の種類 /kernel の動作
C++ 例外処理 無効。 throw キーワードと try キーワードのすべてのインスタンスは、コンパイラ エラーを発生させます (例外指定 throw() の場合を除く)。 すべての /EH オプションは、/kernel と互換性がありません (/EH- の場合を除く)。
RTTI 無効。 dynamic_cast キーワードと typeid キーワードのすべてのインスタンスは、コンパイラ エラーを発生させます (dynamic_cast が静的に使用されている場合を除く)。
new および delete new() または delete() 演算子を明示的に定義する必要があります。 コンパイラとランタイムでは、既定の定義は提供されません。

/kernel オプションを使用する場合、カスタム呼び出し規則、/GS ビルド オプション、およびすべての最適化は許可されます。 インライン展開は、コンパイラによって受け入れられるのと同じセマンティクスを使用すれば、/kernel による大きな影響を受けません。 インライン展開の __forceinline 修飾子が確実に受け入れられるようにするには、警告 C4714 が有効になっていることを確認して、特定の __forceinline 関数がインライン化されていない場合に通知が送られるようにする必要があります。

#pragma には、このオプションを制御するための相当するものはありません。

コンパイラに /kernel スイッチが渡されると、_KERNEL_MODE という名前のプリプロセッサ マクロが生成され、値 1 が設定されます。 このマクロを使用すると、実行環境がユーザー モードかカーネル モードかに基づいて、条件付きでコードをコンパイルすることができます。 たとえば、次のコードでは、カーネル モードの実行用にコンパイルされる場合に、MyNonPagedClass クラスをページング不可のメモリ セグメントに配置するように指定しています。

#ifdef _KERNEL_MODE
#define NONPAGESECTION __declspec(code_seg("$kerneltext$"))
#else
#define NONPAGESECTION
#endif

class NONPAGESECTION MyNonPagedClass
{
   // ...
};

次に示すターゲット アーキテクチャと /arch オプションの組み合わせの一部は、/kernel と共に使用するとエラーを引き起こします。

  • /arch:SSE/arch:SSE2/arch:AVX/arch:AVX2、および /arch:AVX512 は、x86 ではサポートされません。 /kernel を使用する場合、x86 では /arch:IA32 のみがサポートされます。

  • /arch:AVX/arch:AVX2、および /arch:AVX512 は、/kernel と共に使用する場合、x64 ではサポートされません。

/kernel を使用してビルドすると、リンカーにも /kernel が渡されます。 このオプションがリンカーの動作に与える影響を次に示します。

  • インクリメンタル リンクは無効になります。 コマンド ラインに /incremental を追加すると、リンカーが次の致命的エラーを出力します。

    致命的なエラー LNK1295: '/INCREMENTAL' は '/KERNEL' の指定と互換性がありません。'/INCREMENTAL' なしでリンクしてください

  • リンカーは、各オブジェクト ファイル (またはスタティック ライブラリから含められているすべてのアーカイブ メンバー) を検査し、/kernel オプションを使用してコンパイルされた可能性があるかどうかを確認します。 次の表に示すように、いずれかのインスタンスがこの条件を満たしている場合でも、リンカーは正常にリンクされますが、警告が発行される可能性があります。

    コマンド /kernel obj non-/kernel obj、MASM obj、または cvtres obj /kernel と non-/kernel objs の組み合わせ
    link /kernel はい はい はい (警告 LNK4257 あり)
    link はい イエス はい

    LNK4257 リンク オブジェクトは /KERNEL と共にはコンパイルされません。イメージは実行されない可能性があります

/kernel オプションと /driver オプションは、それぞれ独立して動作します。 互いに影響を与えることはありません。

Visual Studio で /kernel コンパイラ オプションを設定するには

  1. プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳しくは、「Visual Studio で C++ コンパイラとビルド プロパティを設定する」をご覧ください。

  2. [構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。

  3. [追加のオプション] ボックスに、/kernel を追加します。 [OK] または [適用] を選択して、変更内容を保存します。

関連項目

MSVC コンパイラ オプション
MSVC コンパイラ コマンド ラインの構文