.NET Native とコンパイル.NET Native and Compilation

.NET Framework を対象にした Windows 8.1 アプリケーションと Windows デスクトップ アプリケーションは特定のプログラミング言語で記述し、中間言語 (IL: Intermediate Language) にコンパイルされます。Windows 8.1 applications and Windows Desktop applications that target the.NET Framework are written in a particular programming language and compiled into intermediate language (IL). 実行時には、メソッドが初めて実行される直前に JIT (Just-In-Time) コンパイラによって IL がローカル コンピューターのネイティブ コードにコンパイルされます。At runtime, a just-in-time (JIT) compiler is responsible for compiling the IL into native code for the local machine just before a method is executed for the first time. それとは対照的に、.NET ネイティブ ツール チェーンでは、コンパイル時にソース コードをネイティブ コードに変換します。In contrast, the .NET Native tool chain converts source code to native code at compile time. このトピックでは、.NET ネイティブを、.NET Framework アプリをコンパイルする他のテクノロジと比較します。また、.NET ネイティブがネイティブ コードをどのように生成するのかについて実践的な概要を説明しますので、.NET ネイティブでコンパイルしたコードで発生する例外が JIT でコンパイルしたコードでは発生しない理由を理解するために役立ちます。This topic compares .NET Native with other compilation technologies available for .NET Framework apps, and also provides a practical overview of how .NET Native produces native code that can help you understand why exceptions that occur in code compiled with .NET Native do not occur in JIT-compiled code.

.NET ネイティブ:ネイティブ バイナリを生成します。.NET Native: Generating native binaries

.NET Framework を対象にしていても、.NET ネイティブ ツール チェーンを使用してコンパイルされないアプリケーションは、次のようなアプリケーション アセンブリで構成されます。An application that targets the .NET Framework and that is not compiled by using the .NET Native tool chain consists of your application assembly, which includes the following:

  • アセンブリ、その依存関係、それに含まれる型、そのメンバーを記述したメタデータMetadata that describes the assembly, its dependencies, the types it contains, and their members. メタデータは、リフレクションと遅延バインディング アクセスのために使用され、場合によってはコンパイラとビルド ツールによって使用されることもあります。The metadata is used for reflection and late-bound access, and in some cases by compiler and build tools as well.

  • 実装コード。Implementation code. これは、中間言語 (IL) オペコードで構成されます。This consists of intermediate language (IL) opcodes. 実行時には、JIT (Just-In-Time) コンパイラが IL コードを対象のプラットフォームのネイティブ コードに変換します。At runtime, the just-in-time (JIT) compiler translates it into native code for the target platform.

これらの主要なアプリケーション アセンブリに加えて、アプリは次の項目の存在を必要とします。In addition to your main application assembly, an app requires that the following be present:

  • アプリに必要な他のすべてクラス ライブラリまたはサード パーティ製のアセンブリ。Any additional class libraries or third-party assemblies that are required by your app. これらのアセンブリには、アプリと同様に、アセンブリ、その型、およびそのメンバーを記述したメタデータが含まれるほか、すべての型のメンバーを実装する IL が含まれます。These assemblies similarly include metadata that describes the assembly, its types, and their members, as well as the IL that implements all type members.

  • .NET Framework クラス ライブラリ。The .NET Framework Class Library. これは、.NET Framework のインストール時にローカル システムにインストールされるアセンブリのコレクションです。This is a collection of assemblies that is installed on the local system with the .NET Framework installation. .NET Framework クラス ライブラリに含まれるアセンブリには、メタデータと実装コードの完全なセットが含まれます。The assemblies included in the .NET Framework Class Library include a complete set of metadata and implementation code.

  • 共通言語ランタイム。The common language runtime. これは、アセンブリの読み込み、メモリ管理とガベージ コレクション、例外処理、JIT コンパイル、リモート処理、および相互運用機能などのサービスを実行するダイナミック リンク ライブラリのコレクションです。This is a collection of dynamic link libraries that perform such services as assembly loading, memory management and garbage collection, exception handling, just-in-time compilation, remoting, and interop. クラス ライブラリと同様に、このランタイムは .NET Framework のインストールの一部としてローカル システムにインストールされます。Like the class library, the runtime is installed on the local system as part of the .NET Framework installation.

アプリを正常に実行するためには、共通言語ランタイム全体だけでなく、アプリケーション固有のアセンブリ、サード パーティ製のアセンブリ、およびシステム アセンブリに含まれるすべての型のメタデータと IL が存在している必要があることに注意してください。Note that the entire common language runtime, as well as metadata and IL for all types in application-specific assemblies, third-party assemblies, and system assemblies must be present for the app to execute successfully.

.NET ネイティブと Just-In-Time コンパイル.NET Native and just-in-time compilation

.NET ネイティブ ツール チェーンへの入力は、C# または Visual Basic コンパイラでビルドされた Windows ストア アプリです。The input for the .NET Native tool chain is the Windows store app built by the C# or Visual Basic compiler. したがって、.NET ネイティブ ツール チェーンの実行が開始されるのは、言語コンパイラが Windows ストア アプリのコンパイルを終了した時点です。In other words, the .NET Native tool chain begins execution when the language compiler has finished compilation of a Windows Store app.

ヒント

.NET ネイティブへの入力は、マネージド アセンブリ向けに記述された IL とメタデータであるため、ビルド前またはビルド後のイベントを使用するか、または MSBuild プロジェクト ファイルを変更することにより、カスタム コードの生成やその他のカスタム操作を実行する余地があります。Because the input to .NET Native is the IL and metadata written to managed assemblies, you can still perform custom code generation or other custom operations by using pre-build or post-build events or by modifying the MSBuild project file.

ただし、IL を変更する種類のツール、つまり .NET ツール チェーンがアプリの IL を解析することを妨げるツールはサポートされません。However, categories of tools that modify IL and thereby prevent the .NET tool chain from analyzing an app's IL are not supported. 難読化ツールは、この種類のツールとして代表的なものです。Obfuscators are the most notable tools of this type.

アプリを IL からネイティブ コードに変換する過程で、.NET ネイティブ ツール チェーンは次のような操作を実行します。In the course of converting an app from IL to native code, the .NET Native tool chain performs operations like the following:

  • 特定のコード パスについて、リフレクションやメタデータに依存するコードを、静的なネイティブ コードで置き換えます。For certain code paths, it replaces code that relies on reflection and metadata with static native code. たとえば、値型が ValueType.Equals メソッドをオーバーライドしない場合、等しいかどうかの既定のテストは、リフレクションを使用して値型のフィールドを表す FieldInfo オブジェクトを取得することによって行われるため、2 つのインスタンスのフィールド値の比較になります。For example, if a value type does not override the ValueType.Equals method, the default test for equality uses reflection to retrieve FieldInfo objects that represent the value type's fields, then compares the field values of two instances. ネイティブ コードにコンパイルするとき、.NET ネイティブ ツール チェーンは、このリフレクションのコードとメタデータをフィールド値の静的な比較に置き換えます。When compiling to native code, the .NET Native tool chain replaces the reflection code and metadata with a static comparison of the field values.

  • 可能であれば、すべてのメタデータを削除しようとします。Where possible, it attempts to eliminate all metadata.

  • アプリにより実際に呼び出される実装コードのみを、最終的なアプリ アセンブリに組み込みます。It includes in the final app assemblies only the implementation code that is actually invoked by the app. これによる効果は、特にサード パーティ製ライブラリや、.NET Framework クラス ライブラリの場合に発揮されます。This particularly affects code in third-party libraries and in the .NET Framework Class Library. この操作の結果として、アプリケーションはサード パーティ製のライブラリにも完全な .NET Framework クラス ライブラリにも依存しなくなり、サード パーティ製のライブラリおよび .NET Framework クラス ライブラリに含まれるコードがアプリに対してローカルになります。As a result, an application no longer depends on either third-party libraries or the full .NET Framework Class Library; instead, code in third-party and .NET Framework class libraries is now local to the app.

  • 完全な CLR を、主としてガベージ コレクターを含む、リファクタリングされたランタイムに置き換えます。It replaces the full CLR with a refactored runtime that primarily contains the garbage collector. リファクタリングされたランタイムは、アプリに対してローカルで、サイズがわずか数百キロバイトの mrt100_app.dll という名前のライブラリに含まれます。The refactored runtime is found in a library named mrt100_app.dll that is local to the app and is only a few hundred kilobytes in size. これが可能になるのは、静的リンクを使用することにより、共通言語ランタイムによって実行されるサービスの多くが不要になるためです。This is possible because static linking eliminates the need for many of the services performed by the common language runtime.

    注意

    .NET ネイティブでは、標準の共通言語ランタイムと同じガベージ コレクターが使用されます。.NET Native uses the same garbage collector as the standard common language runtime. .NET ネイティブのガベージ コレクターでは、既定でバックグラウンド ガベージ コレクションが既定で有効になります。In the .NET Native garbage collector, background garbage collection is enabled by default. ガベージ コレクションの詳細については、「ガベージ コレクションの基礎」を参照してください。For more information about garbage collection, see Fundamentals of Garbage Collection.

重要

.NET ネイティブは、アプリケーション全体をネイティブ アプリケーションにコンパイルします。.NET Native compiles an entire application to a native application. ネイティブ コードに対するクラス ライブラリを含む 1 つのアセンブリをコンパイルして、マネージド コードから独立して呼び出せるようにすることはできません。It does not allow you to compile a single assembly that contains a class library to native code so that it can be called independently from managed code.

.NET ネイティブ ツール チェーンによって生成される結果のアプリは、プロジェクト ディレクトリの Debug または Release ディレクトリ内の ilc.out という名前のディレクトリに出力されます。The resulting app that is produced by the .NET Native tool chain is written to a directory named ilc.out in the Debug or Release directory of your project directory. これは次のようなファイルで構成されます。It consists of the following files:

  • <アプリ名>.exe。<アプリ名>.dll 内の特殊な Main エクスポートに制御を移すだけのスタブ実行可能ファイルです。<appName>.exe, a stub executable that simply transfers control to a special Main export in <appName>.dll.

  • <アプリ名>.dll。すべてのアプリケーション コードのほか、依存関係のある .NET Framework クラス ライブラリおよびサード パーティ製のライブラリを格納した Windows のダイナミック リンク ライブラリです。<appName>.dll, a Windows dynamic link library that contains all your application code, as well as code from the .NET Framework Class Library and any third-party libraries that you have a dependency on. さらに、たとえば Windows と相互運用するために必要なコードや、アプリ内のオブジェクトをシリアル化するために必要なコードなどのサポート コードも格納しています。It also contains support code, such as the code necessary to interoperate with Windows and to serialize objects in your app.

  • mrt100_app.dll。リファクタリングしたランタイムであり、ガベージ コレクションなどのランタイム サービスを提供します。mrt100_app.dll, a refactored runtime that provides runtime services such as garbage collection.

すべての依存関係は、アプリの APPX マニフェストによってキャプチャされます。All dependencies are captured by the app's APPX manifest. appx パッケージに直接バンドルされるアプリケーションの exe、dll、および mrt100_app.dll に加えて、さらに次の 2 つのファイルが含まれます。In addition to the application exe, dll, and mrt100_app.dll, which are bundled directly in the appx package, this includes two more files:

  • msvcr140_app.dll。mrt100_app.dll によって使用される C ランタイム (CRT) ライブラリです。msvcr140_app.dll, the C run-time (CRT) library used by mrt100_app.dll. これはパッケージ内のフレームワーク参照によって組み込まれます。It is included by a framework reference in the package.

  • mrt100.dll。mrt100.dll. mrt100_app.dll のパフォーマンスを向上させる関数が含まれるライブラリですが、このファイルが存在しなくても mrt100_app.dll は機能します。This library includes functions that can improve the performance of mrt100_app.dll, although its absence does not prevent mrt100_app.dll from functioning. これが存在する場合は、ローカル コンピューターの system32 ディレクトリから読み込まれます。It is loaded from the system32 directory on the local machine, if it is present.

.NET ネイティブ ツール チェーンはアプリが実際に呼び出すことがわかっている実装コードのみをアプリにリンクするため、次のシナリオで必要なメタデータや実装コードはアプリに組み込まれないことがあります。Because the .NET Native tool chain links implementation code into your app only if it knows that your app actually invokes that code, either the metadata or the implementation code required in the following scenarios may not be included with your app:

  • リフレクション。Reflection.

  • 動的呼び出しまたは遅延バインディング呼び出し。Dynamic or late-bound invocation.

  • シリアル化と逆シリアル化。Serialization and deserialization.

  • COM 相互運用。COM interop.

必要なメタデータや実装コードが実行時に存在しない場合は、.NET ネイティブ ランタイムが例外をスローします。If the necessary metadata or implementation code is absent at runtime, the .NET Native runtime throws an exception. これらの例外を回避し、必要なメタデータと実装コードが .NET ネイティブ ツール チェーンによって組み込まれたことを確認するには、ランタイム ディレクティブ ファイルという XML ファイルを使用します。このファイルでは、実行時に利用可能であることが必要なメタデータまたは実装コードを含むプログラム要素を指定し、それらのプログラム要素にランタイム ポリシーを割り当てます。You can prevent these exceptions, and ensure that the .NET Native tool chain includes the required metadata and implementation code, by using a runtime directives file, an XML file that designates the program elements whose metadata or implementation code must be available at runtime and assigns a runtime policy to them. .NET ネイティブ ツール チェーンでコンパイルした Windows ストア プロジェクトに追加される既定のランタイム ディレクティブ ファイルは次のとおりです。The following is the default runtime directives file that is added to a Windows Store project that is compiled by the .NET Native tool chain:

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">  
  <Application>  
    <Assembly Name="*Application*" Dynamic="Required All" />  
  </Application>  
</Directives>  

これにより、アプリ パッケージ内のすべてのアセンブリに含まれるすべての型と、それに含まれるすべてのメンバーのリフレクションと動的呼び出しが可能になります。This enables all the types, as well as all their members, in all the assemblies in your app package for reflection and dynamic invocation. ただし、.NET Framework クラス ライブラリ アセンブリに含まれる型のリフレクションと動的なアクティブ化は可能になりません。However, it does not enable reflection or dynamic activation of types in .NET Framework Class Library assemblies. 多くの場合、これで十分です。In many cases, this is adequate.

.NET ネイティブと NGEN.NET Native and NGEN

ネイティブ イメージ ジェネレーター (NGEN) は、アセンブリをネイティブ コードにコンパイルして、ローカル コンピューター上のネイティブ イメージ キャッシュにインストールします。The (Native Image Generator (NGEN) compiles assemblies to native code and installs them in the native image cache on the local computer. ただし、NGEN は、ネイティブ コードを生成するという点では .NET ネイティブと同じですが、いくつかの重要な点で .NET ネイティブと異なります。However, although NGEN, like .NET Native, produces native code, it differs from .NET Native in some significant ways:

  • NGEN は、特定のメソッドのネイティブ イメージを利用できない場合に、コードの JIT 処理にフォールバックします。If no native image is available for a particular method, NGEN falls back to JITing code. このため、NGEN が JIT コンパイルにフォールバックする必要がある場合に備えて、メタデータと IL をネイティブ イメージに組み込んでおく必要があります。This means that native images must continue to include metadata and IL in the event that NGEN needs to fall back to JIT compilation. これに対して、.NET ネイティブではネイティブ イメージのみが生成され、JIT コンパイルにフォールバックすることはありません。In contrast, .NET Native produces only native images and does not fall back to JIT compilation. その結果、一部のリフレクション、シリアル化、および相互運用機能のシナリオに必要なメタデータのみを保持すれは十分です。As a result, only metadata required for some reflection, serialization, and interop scenarios must be preserved.

  • NGEN は、次に挙げるサービスについて完全な共通言語ランタイムに引き続き依存します。アセンブリの読み込み、リモート処理、相互運用性、メモリ管理、ガベージ コレクションなどと、必要な場合は JIT コンパイルです。NGEN continues to rely on the full common language runtime for services such as assembly loading, remoting, interop, memory management, garbage collection, and, if necessary, JIT compilation. .NET ネイティブでは、これらのサービスの多くが不要か (JIT コンパイル)、ビルド時に解決されてアプリのアセンブリに組み込まれます。In .NET Native, many of these services are either unnecessary (JIT compilation) or are resolved at build-time and incorporated in the app assembly. これら以外のサービス (最も重要なものはガベージ コレクション) は、はるかに小さい、リファクタリングされた mrt100_app.dll という名前のランタイムに含まれています。The remaining services, the most important of which is garbage collection, are included in a much smaller, refactored runtime named mrt100_app.dll.

  • NGEN イメージは、脆弱な傾向があります。NGEN images tend to be fragile. たとえば、依存関係のあるファイルにパッチや変更が適用された場合は、通常、それを使用するアセンブリも再度 NGEN で処理する必要があります。For example, a patch or change to a dependency typically requires that the assemblies that use it also be re-NGENed. このことは、特に .NET Framework クラス ライブラリに含まれるシステム アセンブリの場合に当てはまります。This is particularly true of system assemblies in the .NET Framework Class Library. これに対して、.NET ネイティブでは、アプリケーションがそれぞれ個別に実行されます。In contrast, .NET Native allows applications to be served independently of one another.

関連項目See also