純粋なコードと検証可能なコード (C++/CLI)

.NET プログラミングに対して、Visual C++ は、混在、純粋、検証可能の 3 種類のコンポーネントおよびアプリケーションの作成をサポートしています。 これらはすべて /clr (共通言語ランタイムのコンパイル) コンパイラ オプションを通じて利用できます。

解説

検証可能なアセンブリの詳細については、以下を参照してください。

混合 (/clr)

混在アセンブリ (/clr でコンパイルされます) はアンマネージとマネージの両方の部分を含み、.NET の機能を利用できるようにする一方で、アンマネージ コードも保持しています。 このため、プロジェクト全体を書き直すことなく、.NET 機能を使用するようにアプリケーションやコンポーネントを更新できます。 Visual C++ を使用してこのようにマネージ コードとアンマネージ コードを混在させる方法を、C++ Interop と呼びます。 詳細については、「混在 (ネイティブおよびマネージ) アセンブリ」および「ネイティブと .NET の相互運用性」を参照してください。

純粋 (/clr:pure)

純粋なアセンブリ (/clr:pure でコンパイルされます) には、ネイティブ型とマネージ データ型の両方を含むことができますが、マネージ関数しか含むことができません。 混在アセンブリと同様に、純粋なアセンブリでも、プラットフォーム呼び出しによりネイティブ DLL との相互運用が実行できるようになりますが (「C++ での明示的な PInvoke (DllImport 属性) の使用方法」を参照)、C++ Interop 機能は利用できません。 さらに、純粋なアセンブリのエントリ ポイントは __clrcall 呼び出し規約を使用するため、純粋なアセンブリではネイティブ関数から呼び出される関数をエクスポートできません。

/clr:pure の利点

  • 優れたパフォーマンス : 純粋なアセンブリには MSIL だけが含まれ、ネイティブ関数は含まれていないため、マネージとアンマネージ間の遷移は不要です (ただし、プラットフォーム呼び出しによって行われる関数呼び出しは例外です)。

  • AppDomain 対応 : マネージ関数と CLR データ型は、それらの参照可能範囲やアクセシビリティに影響する Application Domains 内に存在しています。 純粋なアセンブリはドメインに対応しているため (__declspec(appdomain) が各型で指定されます)、他の .NET コンポーネントからその型および関数に、より簡単かつ安全にアクセスできます。 その結果、純粋なアセンブリは混在アセンブリよりも安全に他の .NET コンポーネントとの相互運用が実行できます。

  • ディスクへの読み込みなし : 純粋なアセンブリはメモリに読み込んだりストリームしたりできます。 これは、.NET アセンブリをストアド プロシージャとして使用する場合の基本です。 この点は混在アセンブリとの相違点であり、混在アセンブリは Windows の読み込み機構に依存しているため、実行するにはディスク上に存在している必要があります。

  • リフレクション : 混在実行可能ファイルではリフレクションは使用できませんが、純粋なアセンブリはリフレクションを完全にサポートしています。 詳細については、「リフレクション (C++/CLI)」を参照してください。

  • ホストの制御性 : 純粋なアセンブリには MSIL だけが含まれるため、CLR をホストしてその既定の動作を変更するアプリケーションで使用する場合、純粋なアセンブリは混在アセンブリよりも予測可能で柔軟な動作をします。

/clr:pure の制限

ここでは、/clr:pure で現在サポートされていない機能について説明します。

  • 純粋なアセンブリはアンマネージ関数から呼び出すことができません。 したがって、純粋なアセンブリは COM インターフェイスを実装したりネイティブ コールバックを公開したりできません。 純粋なアセンブリは __declspec(dllexport) または .DEF ファイルを使用して関数をエクスポートすることはできません。 また、__clrcall 規約で宣言された関数を、__declspec(dllimport) を使用してインポートすることはできません。 ネイティブ モジュールの関数を純粋なアセンブリから呼び出すことはできますが、純粋なアセンブリはネイティブ呼び出し可能関数を公開できません。そのため、純粋なアセンブリの公開機能は、混在アセンブリでマネージ関数をとおして実行する必要があります。 詳細については、「方法: /clr:pure に移行する (C++/CLI)」を参照してください。

  • ATL ライブラリと MFC ライブラリは、Visual C++ の純粋モード コンパイルではサポートされません。

  • 純粋な .netmodule は、Visual C++ リンカーの入力として受け付けられません。 ただし、純粋な .obj ファイルはリンカーによって受け付けられ、.obj ファイルには netmodule に含まれる情報のスーパーセットが含まれます。 詳細については、「リンカー入力としての .netmodule ファイル」を参照してください。

  • コンパイラ COM サポート (#import) は純粋なアセンブリにアンマネージ命令を導入する可能性があるため、サポートされていません。

  • アラインメントと例外処理の浮動小数点オプションを、純粋なアセンブリに合わせて調整することはできません。 結果的に、__declspec(align) を使用できません。 そのため、fpieee.h などのヘッダー ファイルは /clr:pure と互換性がありません。

  • PSDK の GetLastError 関数を /clr:pure でコンパイルした場合の動作は未定義です。

検証可能 (/clr:safe)

/clr:safe コンパイラ オプションは、Visual Basic や C# で記述されるものと同様の検証可能なアセンブリを生成します。このアセンブリは、コードが現在のセキュリティ設定に違反していないことを共通言語ランタイム (CLR: Common Language Runtime) が保証するために必要な条件に適合します。 たとえば、コンポーネントによるディスクへの書き込みがセキュリティ設定で禁止されている場合、CLR は検証可能なコンポーネントがこの条件を満たしているかをコードの実行前に確認できます。 CRT は検証可能なアセンブリをサポートしていません (CRT のサポートは、C ランタイム ライブラリの純粋 MSIL バージョンを使用して、純粋なアセンブリで利用できます)。

検証可能なアセンブリには、純粋なアセンブリや混在アセンブリを超える次のような利点があります。

  • セキュリティの向上。

  • これは状況によっては (たとえば SQL コンポーネントで) 必要となります。

  • 将来のバージョンの Windows では、検証可能なコンポーネントやアプリケーションが要求される傾向がますます強まります。

1 つの欠点は、C++ interop 機能を利用できないことです。 検証可能なアセンブリには、マネージ コードによって参照されていない場合でも、アンマネージ関数やネイティブ データ型を含むことはできません。

"safe" という単語が使用されているにもかかわらず、/clr:safe でアプリケーションをコンパイルしたからといってバグがないわけではありません。単に、実行時に CLR がセキュリティ設定を確認できるという意味です。

アセンブリの種類にかかわりなく、プラットフォーム呼び出しによるマネージ アセンブリからネイティブ DLL への呼び出しはコンパイルされますが、セキュリティ設定によっては実行時に失敗することがあります。

注意

コンパイラは渡されますが確認不可能なアセンブリとなる 1 つのコーディング例があります。スコープ解決演算子を使用し、オブジェクト インスタンスを通じて仮想関数を呼び出す場合です。たとえば、MyObj -> A::VirtualFunction(); となります。

参照

その他の技術情報

Visual C++ での .NET プログラミング