MSIL/CIL Reflection EmitによるHello World
MSIL/CILによるHello Worldの実現。
"Hello World"を標準出力に表示するプログラムを直接実行可能なILとして出力するアプリケーション
using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; public class EmitHelloWorld { static void Main(string[] args) { // 動的にアセンブリを生成 AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "HelloWorld"; AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); // モジュールも生成 ModuleBuilder module = assemblyBuilder.DefineDynamicModule("HelloWorld.exe"); // クラスを定義 (.typeディレクティブに対応) TypeBuilder typeBuilder = module.DefineType("HelloWorld", TypeAttributes.Public | TypeAttributes.Class); // "Main" メソッドを定義 (.methodディレクティブに対応) MethodBuilder methodbuilder = typeBuilder.DefineMethod("Main" , MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Public , typeof(void), new Type[] { typeof(string[]) }); // メソッドの内容をILで生成、出力 ILGenerator ilGenerator = methodbuilder.GetILGenerator(); ilGenerator.EmitWriteLine("hello world"); ilGenerator.Emit(OpCodes.Ret); // 型を生成 Type helloWorldType = typeBuilder.CreateType(); // 実行 helloWorldType.GetMethod("Main").Invoke(null, new string[] {null}); // .exeとして実行可能な形式で保存 assemblyBuilder.SetEntryPoint(methodbuilder, PEFileKinds.ConsoleApplication); assemblyBuilder.Save("HelloWorld.exe"); } }
生成したILを実行するだけではつまらないのでPE形式として実行可能なアセンブリをカレントディレクトリに保存しています。
保存されたアセンブリをILDASM等で調べるとこのコードと出力されたILの内容の関係がよく解ると思います。