/kernel (カーネル モード バイナリの作成)
Windows カーネルで実行できるバイナリを作成します。 現在のプロジェクト内のコードは、カーネル モードで実行されるコードに固有の C++ 言語機能の、簡略化されたセットを使用してコンパイルおよびリンクされます。
構文
/kernel
解説
/kernel
オプションを指定すると、どの言語機能がカーネル モードで許容されるかを判別し、カーネル モードの C++ に固有のランタイムの不安定性を回避するのに十分な表現力を持たせるように、コンパイラとリンカーに指示が送られます。 これは、カーネル モードで混乱を発生させる C++ 言語機能の使用を禁止することによって実施されます。 コンパイラは、混乱を発生させる可能性があるものの、無効にはできない可能性がある C++ 言語機能に対して警告を生成します。
/kernel
オプションは、ビルドのコンパイラ フェーズとリンカー フェーズの両方に適用され、プロジェクト レベルで設定されます。 /kernel
スイッチを渡すことで、リンク後の結果のバイナリを Windows カーネルに読み込む必要があることを、コンパイラに示すことができます。 コンパイラは、C++ 言語機能の範囲を、カーネルとの互換性があるサブセットに絞り込むことになります。
次の表は、/kernel
を指定した場合にコンパイラの動作がどのように変わるかを示したものです。
動作の種類 | /kernel の動作 |
---|---|
C++ 例外処理 | Disabled。 throw キーワードと try キーワードのすべてのインスタンスは、コンパイラ エラーを発生させます (例外指定 throw() の場合を除く)。 すべての /EH オプションは、/kernel と互換性がありません (/EH- の場合を除く)。 |
RTTI | Disabled。 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
オプションを使用してコンパイルされた可能性があるかどうかを確認します。 次の表に示すように、いずれかのインスタンスがこの条件を満たしている場合でも、リンカーは正常にリンクされますが、警告が発行される可能性があります。command /kernel
objnon- /kernel
obj、MASM obj、または cvtres obj/kernel
と non-/kernel
objs の組み合わせlink /kernel
はい はい はい (警告 LNK4257 あり) link
はい イエス はい LNK4257 リンク オブジェクトは /KERNEL と共にはコンパイルされません。イメージは実行されない可能性があります
/kernel
オプションと /driver
オプションは、それぞれ独立して動作します。 互いに影響を与えることはありません。
Visual Studio で /kernel コンパイラ オプションを設定するには
プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳しくは、「Visual Studio で C++ コンパイラとビルド プロパティを設定する」をご覧ください。
[構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。
[追加のオプション] ボックスに、
/kernel
を追加します。 [OK] または [適用] を選択して、変更内容を保存します。