Skip to content

Research injecting an interface to resolve open generic members and types to closed ones in the managed static registrar #18356

@rolfbjarne

Description

@rolfbjarne

Ref: https://dotnetfiddle.net/orpEt8
Ref: dotnet/runtime#86649 (comment)

This would certainly speed up calling generic types/members from Objective-C, and might also have a size benefit.

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!;
}

Credit to @simonrozsival for this idea.

Metadata

Metadata

Assignees

Labels

app-sizeenhancementThe issue or pull request is an enhancementperformanceIf an issue or pull request is related to performance

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions