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