• Emit用法


    【转自】https://blog.csdn.net/xiaouncle/article/details/52890037

    本人是从0开始学习Emit的,在学习过程中比较困扰我的就是有很多指令不理解、不会用,查了很多资料最终算是搞明白了,记录下来供大家参考。
    除了在网上查资料外,学习Emit和MSIL的另一种方式是.Net Reflector和ildasm.exe配合使用,.Net Reflector能把MSIL代码转换成C#代码(Emit中的Opcodes指令与MSIL指令对应),ildasm.exe能把C#代码转换为MSIL,当想用Emit实现某一功能但是不知道怎么写时,可以先把该功能的C#代码写出来,再用ildasm.exe将其转换成MSIL,最后根据转化生成的MSIL代码的逻辑来写Emit代码,这个很实用。

    【非静态】Ldstr+OpCodes.Ldarg_1

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });

    ILGenerator ilOfShow = showMethod.GetILGenerator();
    //非静态方法参数索引从1开始
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldarg_1);
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    .Net Reflector转化后的C#代码:

    public class StudyOpCodes
    {
    // Methods
    public void Show(int num1, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", num1, text1);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    【静态】Ldstr和OpCodes.Ldarg_1

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public | MethodAttributes.Static, null, new Type[] { typeof(int), typeof(string) });

    ILGenerator ilOfShow = showMethod.GetILGenerator();
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    //静态方法必参数索引从0开始
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldarg_1);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    .Net Reflector转化后的C#代码:

    public class StudyOpCodes
    {
    // Methods
    public static void Show(int num1, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", num1, text1);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    Ldc_I4和Ldc_I8

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });

    #region Ldc_I4
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    //typeof(int)指的是Int32,数字默认是Int32类型
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //非静态方法参数索引从1开始
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region Ldc_I8
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    //typeof(int)指的是Int32,数字默认是Int32类型
    ilOfShow.Emit(OpCodes.Ldc_I8, Convert.ToInt64(18));
    //非静态方法参数索引从1开始
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(Int64), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    .Net Reflector转化后的C#代码:

    //Ldc_I4
    public class StudyOpCodes
    {
    // Methods
    public void Show(int, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", 0x12, text1);
    }
    }
    //Ldc_I8
    public class StudyOpCodes
    {
    // Methods
    public void Show(int, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", 0x12L, text1);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Ldc_R4和Ldc_R8

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });

    #region Ldc_R4
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    //12.3默认是Double类型
    ilOfShow.Emit(OpCodes.Ldc_R4, (float)12.3);
    //非静态方法参数索引从1开始
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(float), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region Ldc_R8
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    //12.3默认是Double类型
    ilOfShow.Emit(OpCodes.Ldc_R8, 12.3);
    //非静态方法参数索引从1开始
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(double), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    .Net Reflector转化后的C#代码:

    //Ldc_R4
    public class StudyOpCodes
    {
    // Methods
    public void Show(int, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", 12.3f, text1);
    }
    }
    //Ldc_R8
    public class StudyOpCodes
    {
    // Methods
    public void Show(int, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", 12.3, text1);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Ldfld和Stfld

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
    FieldBuilder fieldName = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private);

    #region Ldfld
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    //非静态方法参数索引从1开始
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //OpCodes.Ldfld之前必须OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldfld, fieldName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region Stfld
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    //*非静态方法参数索引从1开始
    //OpCodes.Stfld之前必须OpCodes.Ldarg_0
    //this.Name = text1;
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Stfld, fieldName);
    //this.Name = "guo";
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldstr, "guo");
    ilOfShow.Emit(OpCodes.Stfld, fieldName);
    ////text1.Name = (string) this;
    //ilOfShow.Emit(OpCodes.Ldarg_2);
    //ilOfShow.Emit(OpCodes.Ldarg_0);
    //ilOfShow.Emit(OpCodes.Stfld, fieldName);
    ////堆栈为空
    //ilOfShow.Emit(OpCodes.Ldarg_2);
    //ilOfShow.Emit(OpCodes.Stfld, fieldName);
    ////堆栈为空
    //ilOfShow.Emit(OpCodes.Ldstr,"guo");
    //ilOfShow.Emit(OpCodes.Stfld, fieldName);

    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //OpCodes.Ldfld之前必须OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldfld, fieldName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    .Net Reflector转化后的C#代码:

    //Ldfld
    public class StudyOpCodes
    {
    // Fields
    private string Name;

    // Methods
    public void Show(int, string)
    {
    string.Format("姓名:{1} 年龄:{0}", 0x12, this.Name);
    }
    }
    //Stfld
    public class StudyOpCodes
    {
    // Fields
    private string Name;

    // Methods
    public void Show(int, string text1)
    {
    this.Name = text1;
    this.Name = "guo";
    string.Format("姓名:{1} 年龄:{0}", 0x12, this.Name);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Ldsfld和Stsfld

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
    FieldBuilder fieldName = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private | FieldAttributes.Static);

    #region Ldsfld
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //*OpCodes.Ldsfld之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldsfld, fieldName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region Stsfld
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    //OpCodes.Stsfld之前不能有OpCodes.Ldarg_0,Name = text1;
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Stsfld, fieldName);
    //OpCodes.Stsfld之前不能有OpCodes.Ldarg_0,Name = "guo";
    ilOfShow.Emit(OpCodes.Ldstr, "guo");
    ilOfShow.Emit(OpCodes.Stsfld, fieldName);

    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //OpCodes.Ldsfld之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldsfld, fieldName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    .Net Reflector转化后的C#代码:

    //Ldsfld
    public class StudyOpCodes
    {
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string)
    {
    string.Format("姓名:{1} 年龄:{0}", 0x12, Name);
    }
    }
    //Stsfld
    public class StudyOpCodes
    {
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string text1)
    {
    Name = text1;
    Name = "guo";
    string.Format("姓名:{1} 年龄:{0}", 0x12, Name);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    Ldloc和Stloc

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
    FieldBuilder fieldName = typeBuilder.DefineField("Name", typeof(string), FieldAttributes.Private | FieldAttributes.Static);

    #region Ldloc
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //*OpCodes.Ldloc之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldloc, localName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region Stloc
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
    // OpCodes.Stloc之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldarg_2);
    ilOfShow.Emit(OpCodes.Stloc, localName);
    // OpCodes.Stloc之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldstr, "guo");
    ilOfShow.Emit(OpCodes.Stloc, localName);
    // 【静态字段】str=Name;
    ilOfShow.Emit(OpCodes.Ldsfld, fieldName);
    ilOfShow.Emit(OpCodes.Stloc, localName);
    // 【普通字段】str=this.Name;
    //ilOfShow.Emit(OpCodes.Ldarg_0);
    //ilOfShow.Emit(OpCodes.Ldfld, fieldName);
    //ilOfShow.Emit(OpCodes.Stloc, localName);

    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //OpCodes.Ldloc之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldloc, localName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    .Net Reflector转化后的C#代码:

    //Ldloc
    public class StudyOpCodes
    {
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string)
    {
    string str;
    string.Format("姓名:{1} 年龄:{0}", 0x12, str);
    }
    }
    //Stloc
    public class StudyOpCodes
    {
    // Fields
    private static string Name;

    // Methods
    public void Show(int, string text1)
    {
    string name = text1;//此处的局部变量名之所以为name,是因为第三行赋值代码的原因,如果字段名为Address,那此处的局部变量名就会变成address
    name = "guo";
    name = Name;
    string.Format("姓名:{1} 年龄:{0}", 0x12, name);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    Box和Unbox

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
    FieldBuilder fieldAge = typeBuilder.DefineField("objectAge", typeof(object), FieldAttributes.Private);

    #region Box
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    //*此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    ilOfShow.Emit(OpCodes.Box, typeof(int));
    ilOfShow.Emit(OpCodes.Stfld, fieldAge);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region Unbox
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    LocalBuilder localAge = ilOfShow.DeclareLocal(typeof(int));
    //此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    ilOfShow.Emit(OpCodes.Box, typeof(int));
    ilOfShow.Emit(OpCodes.Stfld, fieldAge);
    //*此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldfld, fieldAge);
    ilOfShow.Emit(OpCodes.Unbox, typeof(int));
    ilOfShow.Emit(OpCodes.Stloc, localAge);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    .Net Reflector转化后的C#代码:

    //Box
    public class StudyOpCodes
    {
    // Fields
    private object objectAge;

    // Methods
    public void Show(int, string)
    {
    this.objectAge = 0x12;
    }
    }
    //Unbox
    public class StudyOpCodes
    {
    // Fields
    private object objectAge;

    // Methods
    public void Show(int, string)
    {
    this.objectAge = 0x12;
    int objectAge = (int) this.objectAge;
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Newobj

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
    FieldBuilder fieldUser = typeBuilder.DefineField("objUser", typeof(User), FieldAttributes.Private | FieldAttributes.Static);

    #region Newobj
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    //*OpCodes.Stsfld不需要OpCodes.Ldarg_0,this.Name = new User();
    ilOfShow.Emit(OpCodes.Newobj, typeof(User).GetConstructor(new Type[0]));
    ilOfShow.Emit(OpCodes.Stsfld, fieldUser);
    LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
    ilOfShow.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfShow.Emit(OpCodes.Ldc_I4, 18);
    //OpCodes.Ldloc之前不能有OpCodes.Ldarg_0
    ilOfShow.Emit(OpCodes.Ldloc, localName);
    ilOfShow.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfShow.Emit(OpCodes.Pop);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    .Net Reflector转化后的C#代码:

    public class StudyOpCodes
    {
    // Fields
    private static User objUser;

    // Methods
    public void Show(int, string)
    {
    string str;
    objUser = new User();
    string.Format("姓名:{1} 年龄:{0}", 0x12, str);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Newarr

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    MethodBuilder showMethod = typeBuilder.DefineMethod("Show", MethodAttributes.Public, null, new Type[] { typeof(int), typeof(string) });
    FieldBuilder fieldArray = typeBuilder.DefineField("objUser", typeof(string[]), FieldAttributes.Private);

    #region 不对数组赋值
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
    //*objUser = new string[3];
    //此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldc_I4, 3);
    ilOfShow.Emit(OpCodes.Newarr, typeof(string));
    ilOfShow.Emit(OpCodes.Stfld, fieldArray);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    #region 对数组赋值
    ILGenerator ilOfShow = showMethod.GetILGenerator();
    LocalBuilder localName = ilOfShow.DeclareLocal(typeof(string));
    //objUser = new string[3];
    //此处的OpCodes.Ldarg_0是OpCodes.Stfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldc_I4, 3);
    ilOfShow.Emit(OpCodes.Newarr, typeof(string));
    ilOfShow.Emit(OpCodes.Stfld, fieldArray);
    //给数组赋值:objUser = new string[] { "aaa", "bbb", "ccc" };
    //此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldfld, fieldArray);
    ilOfShow.Emit(OpCodes.Ldc_I4, 0);
    ilOfShow.Emit(OpCodes.Ldstr, "aaa");
    ilOfShow.Emit(OpCodes.Stelem_Ref);
    //此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldfld, fieldArray);
    ilOfShow.Emit(OpCodes.Ldc_I4, 1);
    ilOfShow.Emit(OpCodes.Ldstr, "bbb");
    ilOfShow.Emit(OpCodes.Stelem_Ref);
    //此处的OpCodes.Ldarg_0是OpCodes.Ldfld所需的
    ilOfShow.Emit(OpCodes.Ldarg_0);
    ilOfShow.Emit(OpCodes.Ldfld, fieldArray);
    ilOfShow.Emit(OpCodes.Ldc_I4, 2);
    ilOfShow.Emit(OpCodes.Ldstr, "ccc");
    ilOfShow.Emit(OpCodes.Stelem_Ref);
    ilOfShow.Emit(OpCodes.Ret);
    #endregion

    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    .Net Reflector转化后的C#代码:

    //不对数组赋值
    public class StudyOpCodes
    {
    // Fields
    private string[] objUser;

    // Methods
    public void Show(int, string)
    {
    this.objUser = new string[3];
    }
    }
    //对数组赋值
    public class StudyOpCodes
    {
    // Fields
    private string[] objUser;

    // Methods
    public void Show(int, string)
    {
    objUser = new string[] { "aaa", "bbb", "ccc" };
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    【构造方法】Ldstr和OpCodes.Ldarg_1

    Emit代码:

    public class StudyOpCodes
    {
    public void Test()
    {
    AssemblyName assemblyName = new AssemblyName("Study");
    AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
    ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("StudyModule", "StudyOpCodes.dll");
    TypeBuilder typeBuilder = moduleBuilder.DefineType("StudyOpCodes", TypeAttributes.Public);
    ConstructorBuilder ctorMethod = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(int), typeof(string) });

    ILGenerator ilOfCtor = ctorMethod.GetILGenerator();
    //非静态方法参数索引从1开始
    ilOfCtor.Emit(OpCodes.Ldstr, "姓名:{1} 年龄:{0}");
    ilOfCtor.Emit(OpCodes.Ldarg_1);
    ilOfCtor.Emit(OpCodes.Ldarg_2);
    ilOfCtor.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(int), typeof(string) }));
    ilOfCtor.Emit(OpCodes.Pop);
    ilOfCtor.Emit(OpCodes.Ret);
    Type t = typeBuilder.CreateType();
    assemblyBuilder.Save("StudyOpCodes.dll");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    .Net Reflector转化后的C#代码:

    public class StudyOpCodes
    {
    // Methods
    public StudyOpCodes(int num1, string text1)
    {
    string.Format("姓名:{1} 年龄:{0}", num1, text1);
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    总结

    除了OpCodes.Ldfld和OpCodes.Stfld命令使用之前需要额外执行OpCodes.Ldarg_0之外,其他命令都不需要。
    上面列出了常用的OpCodes指令的使用方法,当然只是一些基本的使用方法,复杂的使用情况(封装、继承、多态等)在此没有举例,不过有了基础再进一步学习复杂功能的写法也会轻松许多,如果遇到问题就上网或使用.Net Reflector和ildasm.exe来解决,希望对大家有帮助。
    ————————————————
    版权声明:本文为CSDN博主「changuncle」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/xiaouncle/article/details/52890037

  • 相关阅读:
    IOS中多版本,多设备类型支持注意事项
    runtime
    网络搜集各种iOS开源类库
    Foudation框架常用结构体和常用类
    iOS开发-正则表达式的使用方法
    Github上的iOS资料-个人记录
    iOS应用程序多语言本地化
    星期判断
    【设定本地通知为周一到周五提醒, 周末不提醒解决办法】
    iOS9 HTTPS解决办法
  • 原文地址:https://www.cnblogs.com/yy1234/p/11387749.html
Copyright © 2020-2023  润新知