2

我想使用 .NET 对象调用成员函数calli。我可以使用以下代码调用一个静态函数,该函数接受一个 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>|])   

当我调用第二个片段时,我收到以下消息。不用说,我没有使用编组或类似的东西。

运行时遇到致命错误。错误地址位于线程 0x20e50 上的 0xed470d3f。错误代码为 0xc0000005。此错误可能是 CLR 中的错​​误或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括 COM 互操作或 PInvoke 的用户封送错误,这可能会损坏堆栈。

请问我做错了什么?

4

1 回答 1

1

根据文档calli,您正在使用的重载EmitCalli()应该仅用于调用非托管代码。对于托管代码,您应该调用一个需要多一个参数的重载并将其设置为null(除非您正在使用varagrg,这非常罕见):

ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.HasThis, typeof<int>, [|typeof<int>|], null)
于 2013-03-03T20:38:03.880 回答