lui*_*bal 2 .net mono cil exception reflection.emit
我在System.Reflection.Emit使用mono 导出的程序集中遇到了一个奇怪的错误.在尝试运行我的程序集时,我得到一个InvalidProgramException:无效的IL代码.
monodis 给我这个CIL结果(这与我用Emit导出的结果一致):
.method public static hidebysig
default void f_main (class [Pine.Core]Pine.Core.Function A_0, class [Pine.Core]Pine.Core.ValueList A_1) cil managed
{
// Method begins at RVA 0x2144
// Code size 26 (0x1a)
.maxstack 4
.locals init (
class [Pine.Core]Pine.Core.Function V_0,
class [Pine.Core]Pine.Core.IScope V_1,
class [Pine.Core]Pine.Core.ValueList V_2,
class [Pine.Core]Pine.Core.IScope V_3)
IL_0000: ldarg.0
IL_0001: stloc.0
IL_0002: ldarg.1
IL_0003: stloc.2
IL_0004: ldloc.0
IL_0005: ldftn instance class [Pine.Core]Pine.Core.IScope class [Pine.Core]Pine.Core.Function::get_Scope()
IL_000b: stloc.1
IL_000c: ldloc.1
IL_000d: newobj instance void class [Pine.Core]Pine.Core.BlockScope::'.ctor'(class [Pine.Core]Pine.Core.IScope)
IL_0012: stloc.3
IL_0013: ldloc.2
IL_0014: call instance void class [Pine.Core]Pine.Core.ValueList::Clear()
IL_0019: ret
} // end of method PineType::f_main
Run Code Online (Sandbox Code Playgroud)
错误发生在IL_000b: stloc.1
我不知道为什么.
我试图用stloc.1pop指令替换它.当我这样做时,错误发生在IL_0019: ret
我真的不知道为什么这样做.有任何想法吗?
附加信息:
IScope 是一个界面BlockScope 器物 IScopeFunction 有个 public IScope Scope { get; private set; }编辑:从代码判断,也许IL_0005是一个呼叫/ callvirt而不是ldftn?也许发光是使用错误的操作码?
本地1是一个IScope.ldftn将函数指针(native int)推送到评估堆栈.IL_000b上的存储指令无法验证,因为本机int不是验证程序 - 可分配给IScope.
至于你的第二个问题,你已经用IL_0004上的指令使评估堆栈失去平衡.ldftn的堆栈转换是"...... - > ...,ftn".这意味着它不采用评估堆栈参数,只采用直接元数据标记.通过将IL_000b更改为弹出窗口,可以弹出ldftn推送的内容,但不会弹出IL_0004推送的内容.
我不清楚的是你正在尝试做什么.您不能将单个函数指针视为接口(您可以将其视为概念上至少作为指向v表的指针).您需要实例化实现该接口的类型.你可以用函数指针做什么是从它创建一个委托 - Delegate有一个(object,native int)重载.ctor.那就是我假设IL_0004推送的对象引用会起作用的地方(这个.ctor的第一个参数).当然,您也可以直接调用函数指针.由于我不熟悉您正在与之交互的对象模型,我不能说正确的方法是什么.