WorkaroundForGenericUCO.cs

CSharp · Console

/Program.cs

using System;
using System.Runtime.InteropServices;

var inst = new GenericNSObject<Dummy>();
var handle = GCHandle.Alloc(inst);

var res = GenericNSObject_1__Registrar_Callbacks__.DoSomething((IntPtr)handle, 12, true);
Console.WriteLine($"res: {res}");

var res2 = GenericNSObject_1__Registrar_Callbacks__.DoSomething((IntPtr)handle, 24, false);
Console.WriteLine($"res2: {res2}");

class Dummy {}

// app code
public partial class GenericNSObject<T> : NSObject {
    // [Export("blah")]
    public int DoSomething(int p0, bool p1) {
        Console.WriteLine($"{typeof(T)} - {p0}, {p1}");
        return p1 ? p0 : -p0;
    }
}

// generated code
internal interface GenericNSObject_1__GenericsProxy {
    int DoSomething_Proxy(int p0, bool p1);
}

partial class GenericNSObject<T> : GenericNSObject_1__GenericsProxy {
    public int DoSomething_Proxy(int p0, bool p1) => DoSomething(p0, p1);
}

internal static class GenericNSObject_1__Registrar_Callbacks__ {
    // [UnmanagedCallersOnly(EntryPoint = "__calback_123_GenericNSObject_1__DoSomething")]
    public static int DoSomething(IntPtr handle, int p0, bool p1) {
        var obj = Runtime.GetNSObject<GenericNSObject_1__GenericsProxy>(handle);
        return obj.DoSomething_Proxy(p0, p1);
    }
}

public class NSObject
{
}

public class Runtime
{
    public static T GetNSObject<T>(IntPtr handle)
        => (T)GCHandle.FromIntPtr(handle).Target!;
}
;