Using an unmanaged function pointer from managed code
Today, Peter asked me an interesting question he had while implementing OLE2 Drag'n Drop in SWF: he got a native function pointer from unmanaged code and tried to invoke it from managed land. Unfortunately, such a pointer isn't managed to a delegate on .NET 1.x, so we were looking for a little hack. What we need is basically a function which looks like this in IL:
.method static int32 GetData (native int pfn, native int foo, native int bar)
{
ldarg.2 // push bar
ldarg.1 // push foo
ldarg.0 // push pfn
calli unmanaged stdcall native int(native int, native int, native int)
ret
}
However, we wanted to do that without using an extra dll for that - so I had a really cool idea: using a dynamic module.
So here's the code:
static MethodInfo CreateMethod ()
{
AssemblyName aname = new AssemblyName ("temp");
AssemblyBuilder ass = AppDomain.CurrentDomain.DefineDynamicAssembly (
aname, AssemblyBuilderAccess.Run);
ModuleBuilder mb = ass.DefineDynamicModule ("temp");
TypeBuilder tb = mb.DefineType ("Test", TypeAttributes.Public);
Type[] ptypes = new Type[] { typeof (int) };
MethodBuilder method = tb.DefineMethod (
"Hello", MethodAttributes.Static | MethodAttributes.Public,
typeof (int), ptypes);
ILGenerator ig = method.GetILGenerator ();
ig.Emit (OpCodes.Nop);
ig.Emit (OpCodes.Ldc_I4_1);
ig.Emit (OpCodes.Ret);
Type t = tb.CreateType ();
MethodInfo m = t.GetMethod ("Hello");
return m;
}
This returns you a MethodInfo which you can just Invoke.
Note that you need the CreateType() and the GetMethod at the end.
If at all possible, you should also store the returned MethodInfo somewhere and reuse it rather than creating a new one each time.
Posted by
martin at June 02, 2005 12:16 am.