posts - 165,  comments - 880,  trackbacks - 42
最近一直在学习Emit,对指令有一些了解.总结了一些小经验在IL指令中经常的事情就
是把变量,参数推到堆栈上然后call一些方法,来来回回的这样做.下面贴个用DynamicMethod简单实现方法的代码:)
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication1
{
    
class Program
    
{
        
static void Main(string[] args)
        
{


            DynamicMethod dm 
= new DynamicMethod("Test"null,
                
new Type[] typeofstring) },typeof(string).Module);
            ILGenerator il 
= dm.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
//把参数推到堆栈上
            MethodInfo call = typeof(Console).GetMethod("WriteLine"new Type[] typeof(string)});
            il.Emit(OpCodes.Call, call);
//执行Console.WriteLine方法
            il.Emit(OpCodes.Ret);//结束返回
            Action<string> test = (Action<string>)dm.CreateDelegate(typeof(Action<string>));
            test(
"henry");

            
//下面Test1方法和Test完成的方法是一样的,但IL似乎有些不同.
            
//主要体现变量设置,对于变量的位置也会影响指令
            dm = new DynamicMethod("Test1"null,
                
new Type[] typeof(string) }typeof(string).Module);
            il 
= dm.GetILGenerator();
            il.DeclareLocal(
typeof(string));
            il.Emit(OpCodes.Ldarg_0);
//把参数推到堆栈上
            il.Emit(OpCodes.Stloc_0);//把值保存到索引为0的变量里
            il.Emit(OpCodes.Ldloc_0);//把索引为0的变量推到堆栈上
            call = typeof(Console).GetMethod("WriteLine"new Type[] typeof(string) });
            il.Emit(OpCodes.Call, call);
//执行Console.WriteLine方法
            il.Emit(OpCodes.Ret);
             test 
= (Action<string>)dm.CreateDelegate(typeof(Action<string>));
            test(
"henry");

            
//对于下面的方法大家自己推一下,其实很简单.
            
//如果看起来有不明白,不防copy到vs.net上然后看指令描述信息:)
            dm = new DynamicMethod("Test2"null,
               
new Type[] typeof(string) }typeof(string).Module);
            il 
= dm.GetILGenerator();
            il.DeclareLocal(
typeof(string));
            il.Emit(OpCodes.Ldstr, 
"你好 ");
            il.Emit(OpCodes.Ldarg_0);
            call 
= typeof(string).GetMethod("Concat"new Type[] {typeof(string),typeof(string) });
            il.Emit(OpCodes.Call, call);
            il.Emit(OpCodes.Stloc_0);
            il.Emit(OpCodes.Ldloc_0);
            call 
= typeof(Console).GetMethod("WriteLine"new Type[] typeof(string) });
            il.Emit(OpCodes.Call, call);
            il.Emit(OpCodes.Ret);
            test 
= (Action<string>)dm.CreateDelegate(typeof(Action<string>));
            test(
"henry");
            Console.Read();
            


        }

       
    }

}

当你熟了某些指令的时候,事情就变得简单并不是想象中复杂.
posted on 2008-05-21 16:53 henry 阅读(1616) 评论(6)  编辑 收藏 所属分类: Emit

FeedBack:
2008-05-21 17:19 | 浪子      
其实IL跟汇编差不多,每次call都要把参数先push才可以。
印象中好像NBear小组做了一个EmitUtilty,封装了这些操作。
  回复  引用  查看    
#2楼 [楼主]
2008-05-21 17:27 | henry      
@浪子
是的基本就是这些操作对一有些操作搞不明白,也不用怕写一个用ildasm看一下就一目了然.
网上提供一个EmitHelper不错,我不用它的一个原因因为我的IL指令还不是很熟,用OpCodes.有描述提示:)
  回复  引用  查看    
2008-05-22 10:00 | Tony.chen [未注册用户]
请问LZ这个技术用到那些方面,有没有什么具体作用,能不能简要的做个介绍
  回复  引用    
#4楼 [楼主]
2008-05-22 10:11 | henry      
@Tony.chen
现在我一般用il写一些方法来代替反射,还有就是实现接口代理监控所有接口成员的调用处理.
这里有如何用IL生接口方法代理
http://www.cnblogs.com/henryfan/archive/2008/05/22/1204477.html

还有要说明一下这些功能都可以用CodeDom来完成,IL并不是你唯一选择的途径.
  回复  引用  查看    
2008-05-22 15:35 | 紫雨轩 .Net      
DynamicMethod 代替反射优点就是速度快,性能好。
DynamicMethod 还提供了另外一种emit方式,不是一条一条指令的,
而是一次传递整个方法字节码数组的。
对于固定的方法来说这种方式应该更好一些。
  回复  引用  查看    
#6楼 [楼主]
2008-05-22 17:11 | henry      
@紫雨轩 .Net
理论来说只是构造IL速度上快,但到最终运行估计是一样.因为在运行时JIT本地编码,这个时候被JIT的IL代码一样的情况下速度是一样的.

  回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-05-22 10:17 编辑过


相关链接:
 


<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

寻求伯乐,限广州地区有意联系


与我联系

搜索

 

常用链接

留言簿(21)

我参加的小组

我的标签

随笔分类

最新评论