【转自】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

Emit用法的更多相关文章

  1. vue $emit 用法

    1.父组件可以用props传递给子组件. 2.子组件可以利用$emit触发父组件事件. vm.$emit('父组件方法',参数); vm.$on(event,fn); $on监听event事件后运行f ...

  2. 【vue】父向子组件传参、子组件向父传参

    1.父向子组件传参 App.vue为父,引入componetA组件之后,则可以在App.vue中使用标签(注意驼峰写法要改成componet-a写法,因为html对大小写不敏感,componenta与 ...

  3. vue父子组件传值

    1.父组件向子组件传值 例如app.vue是父组件,v-header.vue是子组件,实现app向v-header传值父组件需要自定义自己的title值, 子组件v-header内容 <temp ...

  4. Vue里父子组间的通讯

    父组件代码 <template> <div> <child @child-say="listenToBoy" :mes=count></c ...

  5. Vue的组件及传参

    目录 Vue的组件及传参 Vue组件的概念 根组件 子组件(局部组件) 父组件向子组件传值 子组件向父组件传值 Vue的组件及传参 Vue组件的概念 我们首先要知道组件的概念,实际上每一个组件都是一个 ...

  6. React系列——websocket群聊系统在react的实现

    前奏 这篇文章仅对不熟悉在react中使用socket.io的人.以及websocket入门者有帮助. 下面这个动态图展示的聊天系统是用react+express+websocket搭建的,很模糊吧, ...

  7. vue中$emit 和$on 和$set的用法

    1.$set的用法:给 student对象新增 age 属性 data () { return { student: { name:"里斯'} } } 直接给student赋值不会触发视图更 ...

  8. vue父子间通信案列三($emit和prop用法)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. socket.io中emit和on的用法

    socket.emit('action');表示发送了一个action命令,命令是字符串的,在另一端接收时,可以这么写: socket.on('action',function(){...});soc ...

随机推荐

  1. Apollo简介及项目集成

    1. 产生背景 随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关.参数的配置.服务器的地址…… 对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境.分集群管理配置,完善的权限 ...

  2. windows mysql绿色版配置Mysql5.7.X

    MySQL绿色版安装,很简单按照下面的方式很快就可以实现了. 1.下载地址 https://dev.mysql.com/downloads/mysql/ 百度网盘链接:https://pan.baid ...

  3. 惠普打印机和扫描仪修复医生 HP Print and Scan Doctor

    https://support.hp.com/cn-zh/topic/printscandoctor-printing-problems http://ftp.hp.com/pub/printers/ ...

  4. 2018 遇到selenium.common.exceptions.WebDriverException问题

    selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PAT ...

  5. idea-debug启动会卡住不动,BeanPostProcessors (for example: not eligible for auto-proxying),报错解决

    debug启动会卡住不动,run模式启动正常 debug启动输出到下面这行之后,就不会继续输出了 爆出各种 [INFO]- Bean 'dataSource' of type [class Druid ...

  6. while死循环

    while死循环放入主线程要注意,如果处理不当可能引起界面假死,如果界面假死,可以放入子线程中(如果每个循环处理时间现对于CPU很短,则建议在本次循环结束的尾部加入Sleep以释放对CPU的占用) C ...

  7. 【pip升级导致错误】 多个pip导致明明已经安装了包但是报no module错误

    原来一直用apt install 默认安装的pip 8.01版本,今天因为一些原因,将pip升级到了19.01.升级后就导致了错误. 直接pip installl --upgrade pip,发现报权 ...

  8. Intellij IDEA集成mybatis-generator插件自动生成数据库实体操作类

    Intellij IDEA集成mybatis-generator插件自动生成数据库实体操作类 转载至:https://blog.csdn.net/fishinhouse/article/details ...

  9. 迅速生成项目-react-nextjs

    推荐指数:

  10. IE6利用iframe遮挡 弹层 select

    ie6的老bug了,select老是会挡住 弹层里的内容. 解决办法:(box需要设置高度) <div class="box"> <!--[if IE 6]> ...