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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决