我试图删除IL代码中的Tick事件的订阅,以便它不会触发。
这是IL代码:
IL_0e19: ldftn instance void App.Framework.MainForm::mTimer_Tick(object, class [mscorlib]System.EventArgs)
IL_0e1f: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
IL_0e24: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Timer::add_Tick(class [mscorlib]System.EventHandler)
IL_0e29: ldarg.0
所以我想我应该能够删除最后2行以删除订阅,它应该没问题。
IL_0e24: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Timer::add_Tick(class [mscorlib]System.EventHandler)
IL_0e29: ldarg.0
我用以下代码成功编译了IL代码:
ilasm.exe c:\Framework.il /32bitpreferred /dll
现在,当我尝试启动该程序时,它会抛出异常:
System.InvalidProgramException: JIT Compiler encountered an internal limitation.
如果我在没有任何修改的情况下编译IL,那么程序运行时没有任何异常,因此它正在进行更改。
答案 0 :(得分:4)
ldarg0
无关,可能与下一个操作有关;所以你不应该放弃它。你还在堆栈上留下了一些东西,所以你应该弹出两个值 - 目标实例(加载未显示),而不是删除 callvirt。和事件处理程序实例(来自ldftn
/ newobj
- 请注意,此处还显示了与此步骤相关的未显示的负载)。或者 - 首先不要加载这两个值。可能在IL_0e19
之前发生了很多事情,可能会有一些清理工作。
基本上,给定代码如:
someTimer.Tick += target.SomeMethod;
这是:
您显示的IL开始于"将SomeMethod加载为函数指针",并包含用于下一操作的无关负载。