.NET 4.5 MethodBuilder.SetMethodBody

6
在最新版本的.NET框架4.5中,MethodBuilder类有一个名为SetMethodBody的方法,我认为这正是我正在寻找的替代ILGenerator(它很烦人并且在奇怪的方式上受限)的方法。文档可以在此处找到,尽管.NET 4.5还没有发布,因此它没有完全记录。我可以提供除两个参数外的所有参数,但其余的我需要帮助。
我不理解的第一个是第三个参数byte[] localSignature。MSDN指出,它是“包含序列化本地变量结构的字节数组。如果方法没有局部变量,则指定null。”问题是,这就是它所说的一切,我无法找到“序列化本地变量签名”的格式。我已经尝试在ECMA-335规范中查找,但我只找到了如何在未组装的CIL中指定局部变量。如果有人能帮我弄清楚这一点,我将不胜感激。
此外,最后一个参数是 IEnumerable<int> tokenFixups,它表示“il 中代表可以修改的标记开头的偏移量值集合。如果该方法没有需要修改的标记,则指定为 null。”我猜我不需要使用它们,但我还是想知道它们是什么。谢谢,Brandon

5
你需要使用 SignatureHelper 类。修复只适用于将本地代码转换为 IL 的编译器,例如 C++/CLI。 - Hans Passant
1个回答

5

我的问题的真正答案是以评论的形式发布的,而不是作为答案发布的,所以以防其他人有这个问题... 这是发布的答案:

你需要使用SignatureHelper类。修复仅适用于将本机代码转换为IL的编译器,例如C++/CLI。- Hans Passant Mar 10 at 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);

其中,il是一个带有有效IL指令的byte[](请参见this page),maxStack是为方法在堆栈上保留的位置数的整数,handlers是System.Reflection.Emit.ExceptionHandler[],fixups是一个可以忽略的int[]数组(除了下面提到的一个例外)。

我不同意Hans Passant评论中的一件事,即修补程序不仅适用于将本机代码转换为IL的编译器。我在处理此问题时发现,如果尝试发出对MethodBuilder方法的调用,则会发出错误的指令。查看.NET反编译器中的ILGenerator,我发现他们每次发出方法调用时都会发出一个修补程序。确实为每个方法调用添加一个修补程序解决了这个问题。可能还有其他需要发出修补程序以使其正常工作的地方,但我没有深入研究。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接