Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[managed-static-registrar] Remove use of reflection in UCOs of generi…
…c types (#18421) Closes #18356 In the static UnmanagedCallersOnly methods we don't know the generic parameters of the type we're working with and we need to use this trick to be able to call methods on the generic type without using reflection. When we call a non-generic interface method implemented on a generic class, the .NET runtime will resolve the generic parameters for us. In the implementation of the interface method, we can simply use the generic parameters and generate the same code we usually generate in the UnmanagedCallersOnly callback method. This is an example of the code we generate in addition to user code: ```csharp internal interface __IRegistrarGenericTypeProxy__CustomNSObject_1__ { void __IRegistrarGenericTypeProxy__CustomNSObject_1____SomeMethod (IntPtr p0); } public class CustomNSObject<T> : NSObject, __IRegistrarGenericTypeProxy__CustomNSObject_1__ where T : NSObject { [Export ("someMethod:")] public void SomeMethod (T someInput) { // ... } // generated implementation of the proxy interface: public void __IRegistrarGenericTypeProxy__CustomNSObject_1____SomeMethod (IntPtr sel, IntPtr p0, IntPtr* exception_gchandle) { try { var obj0 = (T) Runtime.GetNSObject<T> (p0); SomeMethod (obj0); } catch (Exception ex) { *exception_gchandle = Runtime.AllocGCHandle (ex); } } // generated registrar callbacks: private static class __Registrar_Callbacks__ { [UnmanagedCallersOnly (EntryPoint = "_callback_1_CustomNSObject_1_SomeMethod")] public unsafe static void callback_1_CustomNSObject_1_SomeMethod (IntPtr pobj, IntPtr sel, IntPtr p0, IntPtr* exception_gchandle) { var proxy = (__IRegistrarGenericTypeProxy__CustomNSObject_1__)Runtime.GetNSObject (pobj); proxy.__IRegistrarGenericTypeProxy__CustomNSObject_1____SomeMethod (sel, p0, exception_gchandle); } } } ``` ```csharp // regular non-generic class for comparison: public class CustomNSObject : NSObject where T : NSObject { [Export ("someMethod:")] public void SomeMethod (NSSet someInput) { // ... } private static class __Registrar_Callbacks__ { [UnmanagedCallersOnly (EntryPoint = "_callback_1_CustomNSObject_1_SomeMethod")] public unsafe static void callback_1_CustomNSObject_1_SomeMethod (IntPtr pobj, IntPtr sel, IntPtr p0, IntPtr* exception_gchandle) { try { NSSet obj0 = Runtime.GetNSObject<NSSet> (p0); SomeMethod (obj0); } catch (Exception ex) { *exception_gchandle = Runtime.AllocGCHandle (ex); } } } } ``` --------- Co-authored-by: Alex Soto <[email protected]>
- Loading branch information
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
Sorry, something went wrong.