emit的ILGenerator2014-06-26在上一篇博客(说说emit(上)基本操作)中,我描述了基 本的技术实现上的需求,难度和目标范围都很小,搭建了基本的架子。在代码中 实现了程序集、模块、类型和方法的创建,唯一的缺憾是方法体。方法体是方法内部的逻辑,我们需要将这个逻辑用IL代码描述出来,然后注入 到方法体内部。这里自然地引出两个主题,IL代码和用来将Il代码注入到方法体 内的工具(ILGenerator)。本篇博客将主要围绕这两个主题展开。但是这一篇博 客不可能将IL讲的很详细,只能围绕ILGenerator的应用来讲解。若想了解IL的全 貌,我想还是要看ECMA的文档了(http://www.ecma- international.org/publications/standards/Ecma-335.htm)。2.1 CIL指令简介这里我们通过几个简单例子来对IL指令有个初步的认识。新建一个名为“HelloWorld”的控制台项目,代码如清单2-1(虽 然在我之前的文章里用过HelloWorld来解释Il,虽然无数篇博客都用过这个例子 ,但是我还是不厌其烦的用它)。代码清单2-1 HelloWorldusing System;namespace HelloWorld{class Program{static void Main(string[] args){Console.WriteLine("Hello World");}}}编译上面的代码,然后使用ILDasm打开HelloWorld.exe,导出.il文件,内容如 下:// Microsoft (R) .NET Framework IL Disassembler. Version 4.0.30319.1// Copyright (c) Microsoft Corporation. All rights reserved.// Metadata version: v4.0.30319.assembly extern mscorlib{.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .zV.4...ver 4:0:0:0}.assembly HelloWorld{//(略)}.module HelloWorld.exe// MVID: {CBB65270-D266-4B29-BAC1-4F255546CDA6}.imagebase 0x00400000.file alignment 0x00000200.stackreserve 0x00100000.subsystem 0x0003 // WINDOWS_CUI.corflags 0x00020003 // ILONLY 32BITREQUIRED// Image base: 0x049F0000// =============== CLASS MEMBERS DECLARATION ===================.class private auto ansi beforefieldinit HelloWorld.Programextends [mscorlib]System.Object{.method private hidebysig static void Main(string[] args) cil managed{.entrypoint// Code size 13 (0xd).maxstack 8IL_0000: nopIL_0001: ldstr "Hello World"IL_0006: call void [mscorlib] System.Console::WriteLine(string)IL_000b: nopIL_000c: ret} // end of method Program::Main.method public hidebysig specialname rtspecialnameinstance void .ctor() cil managed{// Code size 7 (0x7).maxstack 8IL_0000: ldarg.0IL_0001: call instance void [mscorlib] System.Object::.ctor()IL_0006: ret} // end of method Program::.ctor} // end of class HelloWorld.Program