『.Net反射』ILGenerator.Emit 动态MSIL 编程 入门
转载请标明:舒小龙 http://www.cnblogs.com/shuxiaolong/articles/2924574.html
什么都不说,直接贴代码:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 SetValue();
6 }
7
8 public static void SetValue()
9 {
10 int temp1 = 123;
11 int temp2 = 234;
12 int sum = temp1 + temp2;
13 string sumStr = sum.ToString();
14
15 Console.WriteLine(sumStr);
16 }
17 }
对应的 ILGenerator.Emit 代码:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 //.method public hidebysig static void SetValue() cil managed
6 //{
7 // // 代码大小 30 (0x1e)
8 // .maxstack 2
9 // .locals init ([0] int32 temp1,
10 // [1] int32 temp2,
11 // [2] int32 sum,
12 // [3] string sumStr)
13 // IL_0000: nop
14 // IL_0001: ldc.i4.s 123
15 // IL_0003: stloc.0
16 // IL_0004: ldc.i4 0xea
17 // IL_0009: stloc.1
18 // IL_000a: ldloc.0
19 // IL_000b: ldloc.1
20 // IL_000c: add
21 // IL_000d: stloc.2
22 // IL_000e: ldloca.s sum
23 // IL_0010: call instance string [mscorlib]System.Int32::ToString()
24 // IL_0015: stloc.3
25 // IL_0016: ldloc.3
26 // IL_0017: call void [mscorlib]System.Console::WriteLine(string)
27 // IL_001c: nop
28 // IL_001d: ret
29 //} // end of method Program::SetValue
30 SetValue();
31 }
32
33 public static void SetValue()
34 {
35 DynamicMethod dm = new DynamicMethod("SetValueMethod", null, new Type[] { /*typeof(object), typeof(object)*/ }, true);
36
37 ILGenerator generator = dm.GetILGenerator();
38
39 generator.DeclareLocal(typeof(int)); //声明变量
40 generator.DeclareLocal(typeof(int)); //声明变量
41 generator.DeclareLocal(typeof(int)); //声明变量
42 generator.DeclareLocal(typeof(string)); //声明变量
43
44 //加载参数1,需要注意的是静态方法Ldarg_0对应的是参数1,
45 //实例方法Ldarg_0对应的是this指针,Ldarg_1对应的是参数1,
46 //即每个实例方法都传递一个隐含的this指针
47
48 //int temp1 = 123;
49 //int temp2 = 234;
50 //int sum = temp1 + temp2;
51 //string sumStr = sum.ToString();
52 //Console.WriteLine(sumStr);
53
54 //temp1 = 123
55 generator.Emit(OpCodes.Ldc_I4, 123);
56 generator.Emit(OpCodes.Stloc_0);
57
58 //temp2 = 234
59 generator.Emit(OpCodes.Ldc_I4, 234);
60 generator.Emit(OpCodes.Stloc_1);
61
62 //sum = temp1 + temp2
63 generator.Emit(OpCodes.Ldloc_0);
64 generator.Emit(OpCodes.Ldloc_1);
65 generator.Emit(OpCodes.Add);
66 generator.Emit(OpCodes.Stloc_2);
67
68 //string sumStr = sum.ToString();
69 //ldloca.s sum
70 //call instance string [mscorlib]System.Int32::ToString()
71 //stloc.3
72 //调用成员函数
73 generator.Emit(OpCodes.Ldloca_S, 2); //generator.Emit(OpCodes.Ldloc_2);
74 MethodInfo toStringMethodInfo = typeof(Int32).GetMethod("ToString", new Type[] { });
75 generator.Emit(OpCodes.Call, toStringMethodInfo);
76 //generator.EmitCall(OpCodes.Call, toStringMethodInfo, null); //和上面代码 同意思
77 generator.Emit(OpCodes.Stloc_3);
78
79 //Console.WriteLine(sumStr);
80 //IL_0016: ldloc.3
81 //IL_0017: call void [mscorlib]System.Console::WriteLine(string)
82 //调用静态函数
83 generator.Emit(OpCodes.Ldloc_3);
84 MethodInfo writeLineMethodInfo = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
85 generator.Emit(OpCodes.Call, writeLineMethodInfo);
86 //generator.EmitCall(OpCodes.Call, writeLineMethodInfo, null); //和上面代码 同意思
87
88 //generator.Emit(OpCodes.Pop); //是否是 无返回值函数 调用之后,不用弹出堆栈?
89
90 //return
91 generator.Emit(OpCodes.Ret); //函数执行完成
92
93
94
95
96 //将函数作为 委托
97 VoidNoParamsMethod delegateMethod = (VoidNoParamsMethod)dm.CreateDelegate(typeof(VoidNoParamsMethod));
98 //执行委托
99 delegateMethod.Invoke();
100 }
101
102
103 public delegate void VoidNoParamsMethod();
104 }
--------------------------------------------------------------------------
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 TestClass testClass = new TestClass();
6 testClass.Age = 1234;
7 int age = testClass.Age;
8 Console.WriteLine(age);
9 }
10
11
12
13 }
14
15 public class TestClass
16 {
17 public int Age;
18 }
对应的 ILGenerator.Emit 代码:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 //.method private hidebysig static void Main(string[] args) cil managed
6 //{
7 // .entrypoint
8 // // 代码大小 33 (0x21)
9 // .maxstack 2
10 // .locals init ([0] class ComplexSetValue.TestClass testClass,
11 // [1] int32 age)
12 // IL_0000: nop
13 // IL_0001: newobj instance void ComplexSetValue.TestClass::.ctor()
14 // IL_0006: stloc.0
15 // IL_0007: ldloc.0
16 // IL_0008: ldc.i4 0x4d2
17 // IL_000d: stfld int32 ComplexSetValue.TestClass::Age
18 // IL_0012: ldloc.0
19 // IL_0013: ldfld int32 ComplexSetValue.TestClass::Age
20 // IL_0018: stloc.1
21 // IL_0019: ldloc.1
22 // IL_001a: call void [mscorlib]System.Console::WriteLine(int32)
23 // IL_001f: nop
24 // IL_0020: ret
25 //} // end of method Program::Main
26
27 DynamicMethod dm = new DynamicMethod("SetValueMethod", null, new Type[] { /*typeof(object), typeof(object)*/ }, true);
28
29 ILGenerator generator = dm.GetILGenerator();
30
31 generator.DeclareLocal(typeof(TestClass)); //声明变量
32 generator.DeclareLocal(typeof(int)); //声明变量
33
34 //加载参数1,需要注意的是静态方法Ldarg_0对应的是参数1,
35 //实例方法Ldarg_0对应的是this指针,Ldarg_1对应的是参数1,
36 //即每个实例方法都传递一个隐含的this指针
37
38 //TestClass testClass = new TestClass();
39 //testClass.Age = 1234;
40 //int age = testClass.Age;
41 //Console.WriteLine(age);
42
43 //TestClass testClass = new TestClass();
44 //newobj instance void ComplexSetValue.TestClass::.ctor()
45 ConstructorInfo testClassConstructor = typeof (TestClass).GetConstructor(new Type[] {});
46 generator.Emit(OpCodes.Newobj, testClassConstructor);
47 generator.Emit(OpCodes.Stloc_0);
48
49 //testClass.Age = 1234;
50 //ldloc.0
51 //ldc.i4 0x4d2 //1234
52 //stfld int32 ComplexSetValue.TestClass::Age
53 generator.Emit(OpCodes.Ldloc_0);
54 generator.Emit(OpCodes.Ldc_I4, 1234);
55 FieldInfo fieldInfo = typeof (TestClass).GetField("Age");
56 generator.Emit(OpCodes.Stfld, fieldInfo);
57
58 //int age = testClass.Age;
59 //ldloc.0
60 //ldfld int32 ComplexSetValue.TestClass::Age
61 //stloc.1
62 generator.Emit(OpCodes.Ldloc_0);
63 generator.Emit(OpCodes.Ldfld, fieldInfo);
64 generator.Emit(OpCodes.Stloc_1);
65
66 //Console.WriteLine(age);
67 //ldloc.0
68 //call void [mscorlib]System.Console::WriteLine(object)
69 generator.Emit(OpCodes.Ldloc_1);
70 MethodInfo writeLineMethodInfo = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
71 generator.Emit(OpCodes.Call, writeLineMethodInfo);
72 //generator.EmitCall(OpCodes.Call, writeLineMethodInfo, null); //和上面代码 同意思
73
74 //generator.Emit(OpCodes.Pop); //是否是 无返回值函数 调用之后,不用弹出堆栈?
75
76 //return
77 generator.Emit(OpCodes.Ret); //函数执行完成
78
79
80 //将函数作为 委托
81 VoidNoParamsMethod delegateMethod = (VoidNoParamsMethod)dm.CreateDelegate(typeof(VoidNoParamsMethod));
82 //执行委托
83 delegateMethod.Invoke();
84 }
85 }
86
87 public delegate void VoidNoParamsMethod();
88
89 public class TestClass
90 {
91 public int Age;
92 }