我想使用calli
调用。net对象的成员函数。我可以调用一个静态函数,它接受int型参数并返回int型参数,使用下面的代码就可以了:
// push the int argument
// push the address obtained using Ldftn
ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, typeof<int>, [|typeof<int>|])
// correct result now on stack
我希望可以使用类似下面的代码来调用一个成员函数,该函数也接受int型参数并返回int型参数。Jason Bock的《CIL Programming》认为它应该可以工作,尽管我可能读错了。Reflector也认为有些事情不太正确,并声称调用被混淆了。它的最佳猜测是"return (int) *ptr1(num1);
",这与静态调用的含义相同:
ilg.Emit (OpCodes.Ldarg_0)
// push the int argument
// push the address
ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, typeof<int>, [|typeof<int>|])
当我调用第二个片段时,我得到以下消息。不用说,我没有使用编组或类似的东西。
请问我做错了什么?运行时遇到致命错误。错误的地址在0xed470d3f,线程0x20e50上。错误码为0xc0000005。此错误可能是CLR中的错误,也可能是不安全或不可验证的错误部分用户代码。此错误的常见来源包括userCOM-interop或PInvoke的封送错误,这可能会损坏堆栈。
根据calli
的文档,您正在使用的EmitCalli()
的过载应该仅用于调用非托管代码。对于托管代码,您应该调用一个重载,该重载接受另外一个参数并将其设置为null
(除非您使用的是varagrg
,这是非常罕见的):
ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.HasThis, typeof<int>, [|typeof<int>|], null)