.NET 4.5 MethodBuilder.SetMethodBody

标签 .net cil specifications .net-4.5

在最新版本的 .NET 框架 4.5 版中,MethodBuilder 类有一个名为 SetMethodBody 的方法。我相信这正是我正在寻找的使用 ILGenerator 的替代方案(这很烦人并且以奇怪的方式受到限制)。该文档可以找到 here ,尽管由于 .NET 4.5 尚未推出,但尚未完整记录。我可以提供除两个之外的所有论点,但其余的我需要帮助。

第一个我不明白的是byte[] localSignature ,第三个参数。 MSDN 指出它是“包含序列化局部变量结构的字节数组。如果方法没有局部变量,请指定 null”。问题是,这就是它所说的一切,我找不到“序列化局部变量签名”的格式。我尝试查看 ECMA-335 规范,但我发现的只是如何在未汇编的 CIL 中指定局部变量。如果有人能帮我解决这个问题,我将不胜感激。

此外,最后一个参数是 IEnumerable<int> tokenFixups ,它是“表示 il 中偏移量的值的集合,每个值指定可以修改的标记的开头。如果该方法没有必须修改的标记,则指定 null。”。我怀疑我不需要使用这些,但我还是想知道它们是什么。

谢谢, 布兰登

最佳答案

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

You'll need the SignatureHelper class. Fixups are only for compilers that translate native code to IL, like 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 是 byte[]使用有效的 IL 指令(请参阅 this page ),maxStack 是一个整数,其中包含要在堆栈上为该方法保留的位置数量,处理程序是一个 System.Reflection.Emit.ExceptionHandler[] ,修正是 int[]可以忽略的数组(有一个异常(exception),请参见下文。)

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

关于.NET 4.5 MethodBuilder.SetMethodBody,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9644039/

相关文章:

java - "portable application"是什么意思?

c# - 为 MVC3 和 MVC4 Beta 编写自定义 HtmlHelpers,我应该使用 HtmlString 还是 MvcHtmlString?

c# - 多人纸牌游戏的游戏架构和设计策略

c# - 无参数构造函数的第一个参数是什么?

.net - 通过编译为 CIL 在 Powershell4 中使用 Powershell5 类?

timezone - UNIX 时间戳会随时区变化吗?

map - Go 有迭代器数据类型吗?

asp.net - SQL Server 数据库在触发器执行时挂起

c# - 四舍五入到小数点后两位,不使用银行四舍五入

c# - "nested if"与使用 F# 的 "if and"性能