Pregunta

I would like to call a member function of a .NET object using calli. I can invoke a static function that takes an int and returns an int just fine using the following code:

// 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 

I was hoping that I could use something like the following to call a member function that also takes an int and returns an int. "CIL Programming" by Jason Bock suggests it should work, though I am probably reading it wrong. Reflector also thinks something is not quite right, and claims the call is obfuscated. Its best guess is "return (int) *ptr1(num1);", which is the same thing is says for the static call:

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>|])   

When I invoke the second fragment, I get the following message. Needless to say, I am not using marshalling or anything like that.

The runtime has encountered a fatal error. The address of the error was at 0xed470d3f, on thread 0x20e50. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

What am I doing wrong please?

¿Fue útil?

Solución

According to the documentation for calli, the overload of EmitCalli() you're using should be used only for calling unmanaged code. For managed code, you should call an overload that takes one more parameter and set it to null (unless you're using varagrg, which is extremely rare):

ilg.EmitCalli (OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.HasThis, typeof<int>, [|typeof<int>|], null)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top