# Friday, 02 December 2011
« Custom Modifiers | Main | IKVM.NET 7.0 Released »
Function Pointer Types

In today's snapshot I also added support for function pointer types. The CLI supports both managed and unmanaged function pointer types, however both are unverifiable.

Here's a small C++/CLI example of using a managed function pointer type (in the call method signature):

void func() {
  System::Console::WriteLine("Hello from Func");
}

void call(void (*p)()) {
  p();
}

void main() {
  call(func);
}

Compile this with cl /clr:pure test.cpp and the resulting test.exe will be a managed PE file with these three methods (and a lot of other junk).

Here's an IKVM.Reflection example to create an equivalent foo.exe (without the extra junk):

using System;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;

class Program {
  public static void Main() {
    var u = new Universe();
    var ab = u.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.Save);
    var modb = ab.DefineDynamicModule("Foo", "Foo.exe");
   
    var mb2 = modb.DefineGlobalMethod("func", MethodAttributes.Static, null, null);
    var ilgen = mb2.GetILGenerator();
    ilgen.EmitWriteLine("Hello from Func");
    ilgen.Emit(OpCodes.Ret);
   
    Type func = u.MakeFunctionPointer(u.MakeStandAloneMethodSig(CallingConventions.Standard, null, default(CustomModifiers), null, null, null));
   
    var mb3 = modb.DefineGlobalMethod("call", MethodAttributes.Static, null, new Type[] { func });
    ilgen = mb3.GetILGenerator();
    ilgen.Emit(OpCodes.Ldarg_0);
    ilgen.__EmitCalli(OpCodes.Calli, func.__MethodSignature);
    ilgen.Emit(OpCodes.Ret);
   
    var mb1 = modb.DefineGlobalMethod("main", MethodAttributes.Static, null, null);
    ilgen = mb1.GetILGenerator();
    ilgen.Emit(OpCodes.Ldftn, mb2);
    ilgen.Emit(OpCodes.Call, mb3);
    ilgen.Emit(OpCodes.Ret);
   
    modb.CreateGlobalFunctions();
    ab.SetEntryPoint(mb1);
    ab.Save("Foo.exe");
  }
}

(I should point out that this won't work with today's snapshot, because while writing this I discovered that I had incorrectly added a static Create() method to __StandAloneMethodSig, but that should instead be an instance method on Universe.)

Friday, 02 December 2011 09:43:53 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]