- 浏览: 216828 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
zhangwei412827_:
[flash=200,200][/flash]
js 关键字 in 的使用方法 -
flycatdeng:
.classpath文件在哪里?
AndEngine示例运行环境搭建过程 -
revol:
请问,你是如何调用LSMessage,并弹出窗口的?
Silverlight模拟MSN和QQ即时提示消息框
---------------------------------------------------------------------------------------------------
例子 1: 最简单的语句
public void Test1() { Console.WriteLine("aaaa"); }
生成的IL:
.method public hidebysig instance void Test1() cil managed { .maxstack 8 L_0000: nop L_0001: ldstr "aaaa" L_0006: call void [mscorlib]System.Console::WriteLine(string) L_000b: nop L_000c: ret }
使用ILGenerator的Emit方法,改写为
ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, "aaaa"); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret);
---------------------------------------------------------------------------------------------------
例子 2
public void Test1() { string str = "aaaa"; Console.WriteLine(str); }
生成的IL:
.method public hidebysig instance void Test1() cil managed { .maxstack 1 .locals init ( [0] string str) L_0000: nop L_0001: ldstr "aaaa" L_0006: stloc.0 L_0007: ldloc.0 L_0008: call void [mscorlib]System.Console::WriteLine(string) L_000d: nop L_000e: ret }
使用ILGenerator的Emit方法,改写为:
var str = il.DeclareLocal(typeof(string)); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, "aaaa"); il.Emit(OpCodes.Stloc, str); il.Emit(OpCodes.Ldloc, str); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret);
---------------------------------------------------------------------------------------------------
例子 3 : 运算
public void PrintCube(int i) { int cube = i * i * i; Console.WriteLine(cube); }
生成的IL:
.method public hidebysig instance void PrintCube(int32 i) cil managed { .maxstack 2 // 在 .locals 部分声明所有的局部变量。 .locals init ( [0] int32 cube) // 第一个名局部变量,int 型,名为 cube。索引从 0 开始。 L_0000: nop // no operation. L_0001: ldarg.1 // load argument 第一个方法参数入栈,比如“3”。索引号 从 1 开始,而不是从 0 开始。 L_0002: ldarg.1 // 再次向堆栈压入第一个方法参数,又一个“3”。 L_0003: mul // multiply 计算堆栈最顶上两个数的乘积 3×3,并把结果入栈,即堆栈最顶部是 9 了。 L_0004: ldarg.1 // 再次压入第一个方法参数“3”。 L_0005: mul // 堆栈最顶上是“3”,第二是“9”,计算 3×9,此时 27 入栈。 L_0006: stloc.0 // pop value from stack to local variable 堆栈最顶上的值“27”出栈, //并被赋给索引位置“0”处的局部变量 cube,即内存中变量 cube 的值为“27”。 L_0007: ldloc.0 // 局部变量 cube 的值“27”入栈。 L_0008: call void [mscorlib]System.Console::WriteLine(int32) // 控制台输出堆栈最顶上的32 位整数“27”。 L_000d: nop // no operation. L_000e: ret // return from method. }
使用ILGenerator的Emit方法,改写为:
ILGenerator il = methodBuilder.GetILGenerator(); var cube = il.DeclareLocal(typeof(int)); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Mul); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Mul); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) })); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret);
---------------------------------------------------------------------------------------------------
例子 4 : 循环语句
public void SeparateString(string source) { if (source == null) return; int count = source.Length; char c; for (int i = 0; i < count; i++) { c = source[i]; Console.WriteLine(c); } }
生成的IL:
.method public hidebysig instance void SeparateString(string source) cil managed { .maxstack 2 .locals init ( [0] int32 count, [1] char c, [2] int32 i, [3] bool CS$4$0000) // 索引为“3”的这个布尔型局部变量在 C# 代码中并未显式声明,是编译器编译时添加的, //用于保存执行过程中布尔运算的结果,比如比较 source 是否为空时,以及比较 i<count 时。 L_0000: nop L_0001: ldarg.1 // 方法参数 source 的值入栈。 L_0002: ldnull // “空引用”null入栈。 L_0003: ceq // compare equal 比较栈顶的 null 和第二项的 source 是否相等,并 // 把结果 0(false,source 不为空)或 1(true,source 为空)入栈。 L_0005: ldc.i4.0 // 32 位整型数“0”入栈。 L_0006: ceq // 比较栈顶的“0”和堆栈的第二项,第二项可能是“0”,也可能 // 是“1”。比较的结果“1”或“0”入栈。 L_0008: stloc.3 // 栈顶的“1”或“0”出栈,被保存到索引为“3”的局部变量中。 L_0009: ldloc.3 // 执行后,栈顶为“1”(source 不为空)或“0”(source 为空)。 L_000a: brtrue.s L_000e // branch on non-false or non-null 判断栈顶是否 // 为“1”,如果是,跳转到第“IL_000e”行;否则继续往下执行。 L_000c: br.s L_0036 // unconditional branch 当栈顶为“0”时,才会 // 执行到这一行,这一行的执行结果是程序无条件 // 跳转到第“IL_0036”行。 L_000e: ldarg.1 L_000f: callvirt instance int32 [mscorlib]System.String::get_Length() // 对堆栈最顶上的字符串调用其获取长度的实例方法,长度值被入栈。 // “get_Length()”实际是字符串 Length 属性的“get”部分。 L_0014: stloc.0 // 局部变量 count 被赋值为字符串长度。 L_0015: ldc.i4.0 L_0016: stloc.2 // 局部变量 i 被赋值为 0。 L_0017: br.s L_002e // 无条件跳转到第“IL_002e”行。 L_0019: nop L_001a: ldarg.1 L_001b: ldloc.2 L_001c: callvirt instance char [mscorlib]System.String::get_Chars(int32) // source 中索引为 i 处的 char 值入栈。 L_0021: stloc.1 L_0022: ldloc.1 L_0023: call void [mscorlib]System.Console::WriteLine(char) // char 值被输出到控制台 L_0028: nop L_0029: nop L_002a: ldloc.2 // i 值入栈。 L_002b: ldc.i4.1 // 32 位整数 1 入栈。 L_002c: add // i+1 的结果入栈。 L_002d: stloc.2 // i=i+1。 L_002e: ldloc.2 // i 值入栈。 L_002f: ldloc.0 // count 值入栈。 L_0030: clt // compare less than 比较 i<count 是否为真,比较结果入栈。 L_0032: stloc.3 L_0033: ldloc.3 L_0034: brtrue.s L_0019 // 如果 i<count 则跳转到第“IL_0019”行。 L_0036: ret }
---------------------------------------------------------------------------------------------------
例子 5 : 基本类型
public void SayHello(string toWhom) { int i = 1000; double d = 3.1; float f = 4.2F; Console.WriteLine(i); Console.WriteLine(d); Console.WriteLine(f); }
生成的IL:
.method public hidebysig newslot virtual final instance void SayHello(string toWhom) cil managed { .maxstack 1 .locals init ( [0] int32 i, [1] float64 d, [2] float32 f) L_0000: nop L_0001: ldc.i4 1000 L_0002: stloc.0 L_0003: ldc.r8 3.1 L_000c: stloc.1 L_000d: ldc.r4 4.2 L_0012: stloc.2 L_0013: ldloc.0 L_0014: call void [mscorlib]System.Console::WriteLine(int32) L_0019: nop L_001a: ldloc.1 L_001b: call void [mscorlib]System.Console::WriteLine(float64) L_0020: nop L_0021: ldloc.2 L_0022: call void [mscorlib]System.Console::WriteLine(float32) L_0027: nop L_0028: ret }
---------------------------------------------------------------------------------------------------
例子 5 : if语句
int i = 1; if (i > 1) { Console.WriteLine("i > 1"); } else if (i == 1) { Console.WriteLine("i == 1"); } else { Console.WriteLine("i < 1"); }
生成的IL:
.maxstack 2 .locals init ( [0] int32 i, [1] bool CS$4$0000) L_0000: nop L_0001: ldc.i4.1 L_0002: stloc.0 L_0003: ldloc.0 L_0004: ldc.i4.1 L_0005: cgt L_0007: ldc.i4.0 L_0008: ceq L_000a: stloc.1 L_000b: ldloc.1 L_000c: brtrue.s L_001d L_000e: nop L_000f: ldstr "i > 1" L_0014: call void [mscorlib]System.Console::WriteLine(string) L_0019: nop L_001a: nop L_001b: br.s L_0044 L_001d: ldloc.0 L_001e: ldc.i4.1 L_001f: ceq L_0021: ldc.i4.0 L_0022: ceq L_0024: stloc.1 L_0025: ldloc.1 L_0026: brtrue.s L_0037 L_0028: nop L_0029: ldstr "i == 1" L_002e: call void [mscorlib]System.Console::WriteLine(string) L_0033: nop L_0034: nop L_0035: br.s L_0044 L_0037: nop L_0038: ldstr "i < 1" L_003d: call void [mscorlib]System.Console::WriteLine(string) L_0042: nop L_0043: nop L_0044: ret
使用ILGenerator的Emit方法,改写为:
MethodBuilder methodBuilder = typeBuilder.DefineMethod("If", MethodAttributes.Public, typeof(void), null); ILGenerator il = methodBuilder.GetILGenerator(); var i = il.DeclareLocal(typeof(int)); var b = il.DeclareLocal(typeof(bool)); var lblElse = il.DefineLabel(); var lblElse2 = il.DefineLabel(); var lblEnd = il.DefineLabel(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldc_I4_1); //取整数1,入栈 il.Emit(OpCodes.Stloc, i); //取栈中第一个值,赋值局部变量i il.Emit(OpCodes.Ldloc, i); //局部变量i入栈 il.Emit(OpCodes.Ldc_I4_1); //取整数1,入栈 il.Emit(OpCodes.Cgt); //取栈中前两个值,进行大于比较, //如果第一个值大于第二个值,则将整数值 1 (int32) 入栈;反之,将 0 (int32)入栈。 //此时的值为 1 il.Emit(OpCodes.Ldc_I4_0); //取整数0,入栈 il.Emit(OpCodes.Ceq); //取栈中前两个值,进行等于比较, //如果这两个值相等,则将整数值 1(int32)入栈;否则,将 0 (int32) 入栈 //此时的值为 0 il.Emit(OpCodes.Stloc, b); //取栈中第一个值,赋值局部变量b il.Emit(OpCodes.Ldloc, b); //局部变量b入栈 il.Emit(OpCodes.Brtrue_S, lblElse); //如果为真,控制流转到lblElse标签处,如果为假,继续下一条语句 il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, "i > 1"); //引用字符串 il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //输出字符串 il.Emit(OpCodes.Nop); il.Emit(OpCodes.Br_S, lblEnd); il.MarkLabel(lblElse); //设定标签lblElse il.Emit(OpCodes.Ldloc, i); //局部变量i入栈 il.Emit(OpCodes.Ldc_I4_1); //取整数1,入栈 il.Emit(OpCodes.Ceq); //取栈中前两个值,进行等于比较 il.Emit(OpCodes.Ldc_I4_0); //取整数0,入栈 il.Emit(OpCodes.Ceq); //取栈中前两个值,进行等于比较 il.Emit(OpCodes.Stloc, b); //取栈中第一个值,赋值局部变量b il.Emit(OpCodes.Ldloc, b); //局部变量b入栈 il.Emit(OpCodes.Brtrue_S, lblElse2); //如果为真,控制流转到lblElse2标签处,如果为假,继续下一条语句 il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, "i == 1"); //引用字符串 il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //输出字符串 il.Emit(OpCodes.Nop); il.Emit(OpCodes.Br_S, lblEnd); il.MarkLabel(lblElse2); //设定标签lblElse2 il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, "i < 1"); //引用字符串 il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //输出字符串 il.Emit(OpCodes.Nop); il.MarkLabel(lblEnd); //设定标签lblEnd il.Emit(OpCodes.Ret);
---------------------------------------------------------------------------------------------------
测试完整代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Reflection.Emit; using System.Threading; namespace ILDemo { public class UserInfo { public void Test1() { Console.WriteLine("aaaa"); } /* 各种方法 */ } public class Program { public static void Main(string[] args) { AssemblyName asmName = new AssemblyName(); asmName.Name = "ILDemo"; AssemblyBuilder asmBuilder = Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("MyTestDemo"); TypeBuilder typeBuilder = modBuilder.DefineType( "UserInfo", TypeAttributes.Public, typeof(object), null); MethodBuilder methodBuilder = typeBuilder.DefineMethod("Test1", MethodAttributes.Public, typeof(void), null); ILGenerator il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldstr, "aaaa"); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret); /* 各种方法的Emit的实现 */ Type type = typeBuilder.CreateType(); object userInfo = Activator.CreateInstance(type); MethodInfo _MethodInfo = type.GetMethod("Test1"); _MethodInfo.Invoke(userInfo, null); Console.ReadKey(); } } }
发表评论
-
各种 Comet 技术优缺点对比
2015-12-15 09:16 487script tag iframe a ... -
Web 通信 之 长连接、长轮询(long polling)
2015-12-15 09:09 974Web 通信 之 长连接、长轮询(long polling ... -
java并发编程不得不知道的几件事
2012-11-26 13:35 856多线程编程从来都是一件比较困难的事情,调试多线程程序也相当困难 ... -
C#正则表达式小结
2010-10-21 13:22 974只能输入数字 ... -
常用正则表达式(整理中...)
2010-08-31 15:05 7921 提取中括号[]中内容 strin ... -
IL指令集——比较指令
2010-08-24 14:34 1040Public field Static Ceq ... -
IL指令集——跳转指令
2010-08-24 14:33 1593Public field Static Beq ... -
IL指令集——运算指令
2010-08-24 14:32 1219Public field Static Add ... -
Reflect中MethodInfo使用方法(整理中....)
2010-08-24 13:53 12254using System; using System.Col ... -
Emit学习之旅(2):创建常见元素—基础部分
2010-08-24 13:09 1612上回已经用Emit创建了一个简单的类型。下面接着说说如何为动态 ... -
Emit学习之旅(1):Emit概览
2010-08-24 13:03 1485转载Frog 博客空间:http://www.cnblogs ...
相关推荐
如果使用自定义信号,一定要记得信号是类变量,必须在类中定义,不能在实例方法中定义,否则后面发射信号和连接槽方法时都会报错。 案例: class configWin(ui_configWin.Ui_configWin,QtWidgets.QWidget): def __...
学习Emit的简要教程,非常不错的说明!
ILProperty文件中,第一个类 ILProperty 中void LdValue() 方法 50行:this.il.Emit(OpCodes.Ldnull); 改为一对大括号{} if (this.obj.GetGetMethod().IsStatic) this.il.Emit(OpCodes.Ldnull); else this.target....
Emit 学习资源汇总 Emit 学习资源汇总
emit@resource://devtools/shared/event-emitter.js:178:15 emit@resource://devtools/shared/event-emitter.js:255:5 setNodeFront@resource://devtools/client/framework/selection.js:153:5 onDetached@resource:...
emit.js JavaScript中的高效极简事件发射器。安装它可以与bower或npm一起使用: bower install emit.jsnpm install emit.js在HTML中包含emit.min.js ,并且在全局范围内现在可以使用emit对象: < script type =" ...
解决self.env.emit is not a function报错 报错内容 TypeError: self.env.emit is not a function at /usr/local/share/.config/yarn/global/node_modules/yeoman-generator/lib/index.js:653:22 at ...
$emit触发事件拿不到传递的参数 https://blog.csdn.net/qq_36413371/article/details/102795742
EMIT学习经典实例 EMIT学习经典实例 非常不错的一个实例
大事记事件提供了一种简单的观察者模式,用于订阅和侦听Vapor应用程序中的事件。 这个想法是基于。注册事件和侦听器// Eventstruct ThingHappened : Event { ... }// Listenersstruct NofifyThing : Listener { ... ...
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习; 双向数据绑定:保留了angular的特点,在数据操作方面更为简单; 组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着...
Managed.Reflection, System.Reflection [.Emit ]的托管替换 Managed.ReflectionManaged.Reflection 是对 System.Reflection 和 System.Reflection.Emit的完全管理的替换。 System.Reflection 不同,它不绑定到
前端技术社区总目录有各种各样的前端示例其地址为: https://blog.csdn.net/m0_60387551/article/details/128017725
学习vue-js 讲座名称:【Infron】Vue.js入门-Vue.js时代指导老师:板桥船长技能:前端、javascript、Vue.js、Web 开发 什么是Vue? 与 MVVM 模式的 ViewModel 层对应的视图级库。 如何在相同的组件级别之间进行...
最近学习vuejs看例子中用$on无法监听子组件$emit触发事件: 使用版本 vue.js 2.2.5 参考文献 1.vuejs API 2.解决实例 问题分析 1.之前写的自定义组件事件触发为this.$emit(“myclick”,this.todo.text);,这样this...
GrEmit是一个包含不同助手的库,用于使用Reflection.Emit生成代码,主要的是GroboIL- 的智能包装器。 用法 GroboIL替代了ILGenerator。 除了调用ILGenerator.Emit(OpCode,..),还可以调用GroboIL.OpCode(..)。...
$emit(update: prop, “newPropVulue”) 这个模式,使子组件向父组件传达:更新属性,并抛出新的属性值 .sync 修饰符 是父组件中修改prop值得修饰符 一:什么地方需要用到.sync修饰符呢 当子传父,父级有两数据,而...
纯手工打造Emit实现AOP private static void OverrideMethods(TypeBuilder tb, MethodInfo method) { if (!method.IsPublic|| !method.IsVirtual || IsObjectMethod(method)) return; Type[] paramTypes = ...
use ( createSocket ( 'http://127.0.0.1:8080' , null , { // when server push an server-message event, // it will dispatch an action use server data, on : [ 'server-message' ] , emit : [ // when you ...
Socket.IO 的开源 iOS 客户端,使用 swift 编写。... let socket = SocketIOClient(socketURL: "localhost:8880") ... socket.emit("response", "Hello!") } socket.connect() 标签:Socket