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
Emit用法的更多相关文章
- vue $emit 用法
1.父组件可以用props传递给子组件. 2.子组件可以利用$emit触发父组件事件. vm.$emit('父组件方法',参数); vm.$on(event,fn); $on监听event事件后运行f ...
- 【vue】父向子组件传参、子组件向父传参
1.父向子组件传参 App.vue为父,引入componetA组件之后,则可以在App.vue中使用标签(注意驼峰写法要改成componet-a写法,因为html对大小写不敏感,componenta与 ...
- vue父子组件传值
1.父组件向子组件传值 例如app.vue是父组件,v-header.vue是子组件,实现app向v-header传值父组件需要自定义自己的title值, 子组件v-header内容 <temp ...
- Vue里父子组间的通讯
父组件代码 <template> <div> <child @child-say="listenToBoy" :mes=count></c ...
- Vue的组件及传参
目录 Vue的组件及传参 Vue组件的概念 根组件 子组件(局部组件) 父组件向子组件传值 子组件向父组件传值 Vue的组件及传参 Vue组件的概念 我们首先要知道组件的概念,实际上每一个组件都是一个 ...
- React系列——websocket群聊系统在react的实现
前奏 这篇文章仅对不熟悉在react中使用socket.io的人.以及websocket入门者有帮助. 下面这个动态图展示的聊天系统是用react+express+websocket搭建的,很模糊吧, ...
- vue中$emit 和$on 和$set的用法
1.$set的用法:给 student对象新增 age 属性 data () { return { student: { name:"里斯'} } } 直接给student赋值不会触发视图更 ...
- vue父子间通信案列三($emit和prop用法)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- socket.io中emit和on的用法
socket.emit('action');表示发送了一个action命令,命令是字符串的,在另一端接收时,可以这么写: socket.on('action',function(){...});soc ...
随机推荐
- 宝塔 ssl https无法访问使用
https 使用的是443端口 请确保 云上的与宝塔上的443端口开放即可
- python PIL/cv2/base64相互转换
PIL和cv2是python中两个常用的图像处理库,PIL一般是anaconda自带的,cv2是opencv的python版本.base64在网络传输图片的时候经常用到. ##PIL读取.保存图片方法 ...
- Android从5.0到9.0版本的主要变更
https://www.jianshu.com/p/10bdbf883c46?utm_source=desktop&utm_medium=timeline Android5.0 1.虚拟机 在 ...
- NAXSI means Nginx Anti XSS & SQL Injection. NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX
nbs-system/naxsi: NAXSI is an open-source, high performance, low rules maintenance WAF for NGINXhttp ...
- python+opencv抠图并旋转(根据坐标抠图)
import cv2 import numpy as np def subimage(image, center, theta, width, height): theta *= np.pi / 18 ...
- Docs-.NET-C#-指南-语言参考-预处理器指令:#region(C# 参考)
ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#region(C# 参考) 1.返回顶部 1. #region(C# 参考) 2015/07/20 利用 #region,可以 ...
- 方法不会等待Task执行完才返回数据
- flutter DataTable数据表格
数据表显示原始数据集.它们通常出现在桌面企业产品中.DataTable Widget实现这个组件 文档:https://api.flutter.dev/flutter/material/DataTab ...
- RabbitMQ 入门教程(PHP版) 第五部分:通过主题进行消息分发(Topics)
对于 Message 的 routing_key 字符串格式是有限制的:以点号"."分割的字符表,如php.laravel,并且长度不能超过 255 个字节. 对于 routing ...
- Fastjson 序列化与反序列化
JSON这个类是fastjson API的入口,主要的功能都通过这个类提供. 序列化API // 将Java对象序列化为JSON字符串,支持各种各种Java基本类型和JavaBean public s ...