2012-03-10 155 views
5

在最新版本的.NET Framework 4.5版中,MethodBuilder类有一个名为SetMethodBody的方法,我相信这正是我所看到的,作为使用ILGenerator的替代方法(这是讨厌和有限的奇怪方式)。该文档可以找到here,虽然从.NET 4.5还没有出来,但没有完整的文档。我可以提供除了两个以外的所有参数,但其余的我需要帮助。.NET 4.5 MethodBuilder.SetMethodBody

我不明白的第一个是byte[] localSignature,第三个参数。 MSDN指出它是“一个包含序列化局部变量结构的字节数组,如果该方法没有局部变量,则指定null”。麻烦的是,就是这么说的,我找不到“序列化局部变量签名”的格式。我试过看ECMA-335规范,但是我发现的是如何在未组装的CIL中指定局部变量。如果有人能帮我弄清楚,那将非常感激。

另外,最后一个参数是IEnumerable<int> tokenFixups,它是“代表偏移量的值的集合,其中每个值都指定可以修改的令牌的开始。如果方法没有令牌被修改“。我怀疑我不需要使用这些,但我想知道他们是什么。

感谢, 布兰登

+5

您需要SignatureHelper类。 Fixup仅适用于将本机代码翻译为IL的编译器,如C++/CLI。 – 2012-03-10 13:02:11

+0

@Hans Passant:谢谢你的回答! :) – aboveyou00 2012-03-20 17:51:10

回答

4

真正回答我的问题被张贴的评论,而不是答案,所以如果任何人有过这个问题......这里的发布回答:

您需要SignatureHelper类。 Fixup仅适用于将本机代码翻译为IL的编译器,如C++/CLI。 - Hans Passant 3月10日在13:02

所以......为了得到本地签名的字节数组,可以执行此代码:

var sig = SignatureHelper.GetLocalVarSigHelper(this.module); 
sig.AddArgument(typeof(int)); //Local #0 is of type int 
... 
sig.AddArgument(typeof(string)); //Local #n is of type string 
var sigArray = sig.GetSignature(); 

而且为了设置方法身体上的MethodBuilder,你叫

MethodBuilder.SetMethodBody(il, maxStack, sigArray, handlers, fixups); 

...其中,L为一个byte[]与有效IL指令(见this page),maxStack与斑点的数量的整数保留在堆栈上该方法,处理程序是System.Reflection.Emit.ExceptionHandler[],并且调整信息是int[]数组,可以忽略不计(有一个例外,见下文)。

,我在汉斯帕桑特的评论不同意一件事是,的修正不仅对编译器将本机代码翻译成IL。我在这方面发现时发现,如果您尝试发送对MethodBuilder方法的调用,它会发出错误的指令。在.NET反射器中查看ILGenerator,我发现它们每次发出方法调用时都会发出修复。为每个方法调用添加修正确实解决了这个问题。可能还有其他地方需要发布修复程序才能正常工作,但我没有深入研究它。