我如何从一个DynamicMethod的一个字节组IL? [英] How do I get an IL bytearray from a DynamicMethod?

查看:332
本文介绍了我如何从一个DynamicMethod的一个字节组IL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个有点新奇,我想看看如何IL不同于在运行时产生的光量的代码看起来VS由VS编译器生成的代码,因为我注意到,VS代码往往有不同的性能配置文件下运行对于像转换。

As a bit of a novelty, I'm trying to see how different the IL from light weight code generated at runtime looks vs code generated by the VS compiler, as I noticed that VS code tends to run with a different performance profile for things like casts.

所以我写了下面的代码:

So I wrote the following code::

Func<object,string> vs = x=>(string)x;
Expression<Func<object,string>> exp = x=>(string)x;
var compiled = exp.Compile(); 
Array.ForEach(vs.Method.GetMethodBody().GetILAsByteArray(),Console.WriteLine);
Array.ForEach(compiled.Method.GetMethodBody().GetILAsByteArray(),Console.WriteLine);



不幸的是,这是GetMethodBody显然是由表达式树生成的代码非法操作抛出异常。可我怎么在库的方式(即不与外部工具,除非工具有一个API)来看,通过使用轻量级的代码生成代码生成的代码?

Unfortunately, this throws an exception as GetMethodBody is apparently an illegal operation on code generated by expression trees. How can I in a library manner (i.e. not with an external tool unless the tool has an API) look at the code generated by code using lightweight codegen?

编辑:在第5行发生错误,compiled.Method.GetMethodBody()抛出异常。

the error occurs on line 5, compiled.Method.GetMethodBody() throws the exception.

EDIT2:
有谁知道如何恢复在方法声明的局部变量?或者是有没有办法GetVariables?

Does anyone know how to recover the local variables declared in the method? Or is there no way to GetVariables?

推荐答案

呀,不工作,由Reflection.Emit的生成方法。与IL存储在MethodBuilder的的ILGenerator。你可以把它挖出来了,但你必须要很失望。反思是需要得到的内部和私有成员。这个工作对.NET 3.5SP1:

Yeah, doesn't work, the method is generated by Reflection.Emit. The IL is stored in the MethodBuilder's ILGenerator. You can dig it out but you have to be pretty desperate. Reflection is needed to get to the internal and private members. This worked on .NET 3.5SP1:

using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
...

        var mtype = compiled.Method.GetType();
        var fiOwner = mtype.GetField("m_owner", BindingFlags.Instance | BindingFlags.NonPublic);
        var dynMethod = fiOwner.GetValue(compiled.Method) as DynamicMethod;
        var ilgen = dynMethod.GetILGenerator();
        var fiBytes = ilgen.GetType().GetField("m_ILStream", BindingFlags.Instance | BindingFlags.NonPublic);
        var fiLength = ilgen.GetType().GetField("m_length", BindingFlags.Instance | BindingFlags.NonPublic);
        byte[] il = fiBytes.GetValue(ilgen) as byte[];
        int cnt = (int)fiLength.GetValue(ilgen);
        // Dump <cnt> bytes from <il>
        //...

在.NET 4.0,你将不得不使用伊尔根。的GetType()。BaseType.GetField(...),因为IL发生器被改变,DynamicILGenerator,从的ILGenerator衍生

On .NET 4.0 you'll have to use ilgen.GetType().BaseType.GetField(...) because the IL generator was changed, DynamicILGenerator, derived from ILGenerator.

这篇关于我如何从一个DynamicMethod的一个字节组IL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆