Hi,
I'm trying to use Mono.Cecil to perform an unmanaged call with "calli"
opcodes using this kind of code:
ILProcessor worker =
method.Body.GetILProcessor();
TypeReference returnType =
assembly.MainModule.Import(typeof (int));
TypeReference argType1 =
assembly.MainModule.Import(typeof(int));
TypeReference argType2 =
assembly.MainModule.Import(typeof (void*));
CallSite callSite = new CallSite();
callSite.ReturnType = returnType;
callSite.Parameters.Add(new
ParameterDefinition(argType1));
callSite.Parameters.Add(new
ParameterDefinition(argType2));
callSite.CallingConvention =
MethodCallingConvention.StdCall;
worker.Emit(OpCodes.Ldarg_2);
worker.Emit(OpCodes.Ldarg_3);
worker.Emit(OpCodes.Ldarg_1);
worker.Emit(OpCodes.Calli, callSite);
worker.Emit(OpCodes.Ret);
The code is not calling properly the destination methods (arguments
are screwed up). When looking at generated IL through reflector it
seems that the method is not marked as StdCall neither unmanaged :
.method public hidebysig instance int32 Load(void* ptr, int32 arg1,
void* arg2) cil managed
{
.maxstack 3
.locals init (
[0] int32 num)
L_0000: ldarg.2
L_0001: ldarg.3
L_0002: ldarg.1
L_0003: calli method int32 *(int32, void*)
L_0008: ret
}
On the other side, a C++/CLI equivalent is :
.method public hidebysig instance int32 Test(void* functionPtr, int32
test1, void* test2) cil managed
{
.maxstack 3
.locals (
[0] int32 num)
L_0000: ldarg.2
L_0001: ldarg.3
L_0002: ldarg.1
L_0003: calli method unmanaged stdcall int32
modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall)
*(int32, void*)
L_0008: stloc.0
L_0009: ldloc.0
L_000a: ret
}
How can I declare a CallSite to be unmanaged and forcing it to use
stdcall calling convention with Mono.Cecil?
--
--
mono-cecil