zoukankan      html  css  js  c++  java
  • 『.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     }
  • 相关阅读:
    2017 Multi-University Training Contest 2.Balala Power!(贪心)
    2017ICPCECIC C.A math problem(高次剩余)
    Atcoder 068E
    51nod 1385 凑数字(贪心+构造)
    cf round #418 div2 D. An overnight dance in discotheque(贪心)
    cf round #418 div2 C. An impassioned circulation of affection(暴力)
    cf round #424 div2 E. Cards Sorting(线段树)
    Atcoder 077E
    hdu 6162 Ch’s gift(树链剖分+主席树)
    Educational Codeforces Round 26 D. Round Subset(dp)
  • 原文地址:https://www.cnblogs.com/shuxiaolong/p/2924574.html
Copyright © 2011-2022 走看看