有没有办法查看DynamicMethod的生成的IL代码(在Sigil中)?
我正在使用Sigil创建一个DynamicMethod
并希望看到生成的IL。有没有办法查看DynamicMethod的生成的IL代码(在Sigil中)?
我以前从未与DynamicMethods
合作过,所以也许有一个非常明显的答案,但到目前为止我还没有发现任何东西。
这是similar question,但它很旧,我不知道链接的工具是否适用于VS2013 - 我想也许有更新的东西可用。 将生成的方法存储在程序集中并将其写入磁盘可能有效,但这在开发过程中非常麻烦。顺便说一下,我知道Sigil的CreateDelegate
方法的out string instructions
参数,但这似乎不是“真正的”IL代码(包含例如命名标签),我也不确定这是否是之前或者在Sigil的优化之后。
编辑:我最终创建了一个动态程序集并将其写入磁盘,如@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");
我认为最简单的方法是真正创建一个包含你的方法组装,然后使用ILDASM。这样,您可以保留大部分代码并只替换一些管道(可能用Emit<T>.BuildMethod()
代替Emit<T>.NewDynamicMethod()
)。
这不是最方便的解决方案,因为正如你所说,一些代码更改是必要的,但它是有效的。我最终创建了一个将程序集写入磁盘的单元测试(以便我可以在开发过程中轻松地重新创建它)并复制粘贴Emit代码。 – enzi 2015-03-14 16:25:54
你期待什么样的输出?原始字节?文本?要么...? IIRC,Sigil充当'ILGenerator'之上的一层,所以当它实际上*写入时 - 它不直接负责*反正*。我不知道'delegateInstance.Method.GetMethodBody()。GetILAsByteArray()'是否足以满足你的需求? – 2015-03-13 17:04:04
文字,我猜。我只希望查看用于调试目的的IL代码。我不能使用Ildasm(我想),因为代码是在运行时生成的。我意识到Sigil只是一个抽象概念,我只是想提到它,以防内置的支持。我现在要看看'GetILAsByteArray'方法。 – enzi 2015-03-13 17:33:22
'GetMethodBody'操作抛出一个异常,显然这种方法[不适用于DynamicMethods](http://stackoverflow.com/questions/4146877/how-do-i-get-an-il-bytearray-from- a-dynamicmethod),但感谢提示。 – enzi 2015-03-14 16:28:18