C# Mac OS X/Mono下的Ldfld问题,可能是Mono错误

C# Mac OS X/Mono下的Ldfld问题,可能是Mono错误,c#,.net,cil,jint,C#,.net,Cil,Jint,我使用的是第三方库JInt(JavaScript interpriter),在我切换到Mac OS X之前,它一直运行良好,之后我不断发现异常,经过一些调查,我发现JInt使用动态代码生成来创建某种Js Clr桥。此方法最后有以下说明: code.Emit(OpCodes.Ldnull); FieldInfo fieldInfo = typeof(JsUndefined).GetField("Instance"); code.Emit(OpCodes.Ldfld, fieldInfo); 下面

我使用的是第三方库JInt(JavaScript interpriter),在我切换到Mac OS X之前,它一直运行良好,之后我不断发现异常,经过一些调查,我发现JInt使用动态代码生成来创建某种Js Clr桥。此方法最后有以下说明:

code.Emit(OpCodes.Ldnull);
FieldInfo fieldInfo = typeof(JsUndefined).GetField("Instance");
code.Emit(OpCodes.Ldfld, fieldInfo);
下面是这些行的执行方式(全尺寸屏幕截图)

可以清楚地看到,
fieldInfo
参数不是空的,但在执行这些行时,请注意LDFLD没有参数!(全尺寸屏幕截图):

我当前要执行的语句是Ldnull,我正在执行“介入”(超过Ldnull),并且在Ldfld(全尺寸屏幕截图)上发生BANG异常:


有什么建议吗?

ldfld应该始终带有一个参数,否则您会得到一个无效的CLR,运行时环境应该拒绝加载它(CIL格式错误的程序集在加载时会抛出异常)

因此,我认为由于某种原因,作为此
ldfld
参数的字段引用无法在运行时解析(尽管它在创建代码时存在)。一方面,这就是为什么在IDE中获得没有参数的
ldfld
(它不显示类型,因为它无法加载它),另一方面,在执行这一特定行时会得到null异常


您确定动态创建的程序集正确引用了包含
JsUndefined
类型的程序集吗?代码生成器可以看到它,但生成的代码是否看到它?

ldfld应始终带有参数,否则您将获得无效的CLR,运行时环境应拒绝加载它(CIL格式错误的程序集在加载时会抛出异常)

因此,我认为由于某种原因,作为此
ldfld
参数的字段引用无法在运行时解析(尽管它在创建代码时存在)。一方面,这就是为什么在IDE中获得没有参数的
ldfld
(它不显示类型,因为它无法加载它),另一方面,在执行这一特定行时会得到null异常


您确定动态创建的程序集正确引用了包含
JsUndefined
类型的程序集吗?代码生成器可以看到它,但生成的代码是否看到它?

您描述的这个问题是不同问题的组合:

  • IL反汇编不显示字段操作数。它不仅适用于您的字段,您还可以在ldsfld之前的反汇编中看到它。我不担心这一点,但我鼓励您报告它有一个MonoDevelop错误

  • JInt使用一种奇怪的模式在堆栈上加载一个静态字段。我可以通过发射这种模式在Mono 2.10.6上重现问题和NRE。好消息是它已在master中修复。由于您可以访问JInt的代码,为了防止NRE,您可以修改else分支,使其只需阅读:

    Emit(OpCodes.Ldsfld,typeof(JsUndefined.GetField(“实例”))


这会让你前进。

你描述的这个问题是不同问题的组合:

  • IL反汇编不显示字段操作数。它不仅适用于您的字段,您还可以在ldsfld之前的反汇编中看到它。我不担心这一点,但我鼓励您报告它有一个MonoDevelop错误

  • JInt使用一种奇怪的模式在堆栈上加载一个静态字段。我可以通过发射这种模式在Mono 2.10.6上重现问题和NRE。好消息是它已在master中修复。由于您可以访问JInt的代码,为了防止NRE,您可以修改else分支,使其只需阅读:

    Emit(OpCodes.Ldsfld,typeof(JsUndefined.GetField(“实例”))


这会让你走。

我知道ldfld应该总是有一个论点,我只是不知道如何解决这个问题。。。程序集不是动态创建的,它只是一个动态创建的方法。。。所有东西都在windows下工作……我看到代码将
null
加载到堆栈上,然后尝试从对象加载字段。从
null
加载字段肯定会引发null引用异常。它真的可以在Windows上使用相同的代码吗?真的很奇怪…我在Windows中看不到ILASM,因为那里的反汇编显示了由JIT编译的机器代码,尽管它在那里工作得很有魅力。我假设问题不是因为它加载null,而是因为ldfld没有参数,这样的IL永远不会被编译,如果
JsUndefined::Instance
是一个静态字段(我不知道),ldfld应该看起来像
ldfld void[JInt.Native]JsUndefined::Instance
我知道ldfld应该总是伴随着一个论点,我只是不知道如何解决这个问题。。。程序集不是动态创建的,它只是一个动态创建的方法。。。所有东西都在windows下工作……我看到代码将
null
加载到堆栈上,然后尝试从对象加载字段。从
null
加载字段肯定会引发null引用异常。它真的可以在Windows上使用相同的代码吗?真的很奇怪…我在Windows中看不到ILASM,因为那里的反汇编显示了由JIT编译的机器代码,尽管它在那里工作得很有魅力。我假设问题不是因为它加载null,而是因为ldfld没有参数,这样的IL永远不会被编译,如果
JsUndefined::Instance
是一个静态字段(我不知道),ldfld应该看起来像
ldfld void[JInt.Native]JsUndefined::Instance
那么Jb Evan的答案是正确的。我会提交错误报告,你知道应该在哪里提交吗?我会的