【问题标题】:Is there a way to view the generated IL code of a DynamicMethod (in Sigil)?有没有办法查看生成的 DynamicMethod 的 IL 代码(在 Sigil 中)?
【发布时间】:2015-03-13 17:00:35
【问题描述】:

我正在使用Sigil 创建DynamicMethod,并希望查看生成的IL。

我以前从未与DynamicMethods 合作过,所以也许有一个非常明显的答案,但到目前为止我还没有找到任何东西。

这是一个similar question,但它已经很老了,我不知道链接工具在 VS2013 中是否有效——我想也许有更新的东西可用。 将生成的方法存储在程序集中并将其写入磁盘可能可行,但在开发过程中非常麻烦。

顺便说一下,我知道 Sigil 的 CreateDelegate 方法的 out string instructions 参数,但这似乎不是“真正的”IL 代码(例如包含命名标签),我也不确定是否这是在印记优化之前或之后。

编辑:我最终创建了一个动态程序集并将其写入磁盘,正如@svick 建议的那样。然后可以使用ildasm 查看已发出方法的 IL。如果有人想做同样的事情,这是我使用的代码:

var asmName = new AssemblyName("MyAssembly");
var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save);
var mod = asm.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");
var typeBuilder = mod.DefineType("MyType", TypeAttributes.Public | TypeAttributes.Abstract);

// NOTE: this is Sigil's Emit
var emitter = Emit<MyDelegate>.BuildMethod(typeBuilder, "MyMethod", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard);
// [...] emit calls
emitter.CreateMethod();
asm.Save(asmName.Name + ".dll");

【问题讨论】:

  • 您期望什么样的输出?原始字节?文本?要么...? IIRC,Sigil 充当ILGenerator 之上的一层,所以当它实际上 进行写入时 - 它并不直接负责无论如何。我想知道delegateInstance.Method.GetMethodBody().GetILAsByteArray() 是否足以满足您的需求?
  • 文本,我猜。我只想查看 IL 代码以进行调试。我不能使用 Ildasm(我想),因为代码是在运行时生成的。我意识到 Sigil 只是一个抽象,我只是想我会提到它,以防它也有内置支持。我先看看GetILAsByteArray 方法。
  • GetMethodBody 操作抛出异常,显然是这个方法doesn't work for DynamicMethods,不过感谢提示。

标签: c# il emit dynamicmethod ilgenerator


【解决方案1】:

我认为最简单的方法是实际创建一个包含您的方法的程序集,然后在其上使用 ildasm。这样,您可以保留大部分代码,并且只替换一些管道(可能将 Emit&lt;T&gt;.NewDynamicMethod() 替换为 Emit&lt;T&gt;.BuildMethod())。

【讨论】:

  • 这不是最方便的解决方案,因为正如您所说,一些代码更改是必要的,但它可以工作。我最终创建了一个单元测试,将程序集写入磁盘(以便我可以在开发过程中轻松地重新创建它)并复制粘贴 Emit 代码。
猜你喜欢
  • 1970-01-01
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2017-05-18
  • 2010-09-07
  • 2021-04-13
相关资源
最近更新 更多