-
Notifications
You must be signed in to change notification settings - Fork 520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CoreGraphics] Adjust CGPDFOperatorTable to not use a generic Action delegate. #11560
[CoreGraphics] Adjust CGPDFOperatorTable to not use a generic Action delegate. #11560
Conversation
…delegate. * CoreCLR doesn't support generic Action delegates in reverse (P/Invokes), so we need to find a different solution. * The native CGPDFOperatorTable callback API is not very friendly to us, because we can't pass it callback-specific data, which means that the managed caller must conform to the FullAOT requirement of the managed callback (must be a static function; must have a MonoPInvokeCallback attribute). * We can leverage the new function pointer syntax in C# 9 to make these requirements enforced by the C# compiler (unmanaged function pointer + UnmanagedCallersOnly attribute). The resulting API is still clunky to use, but I don't see any way around that. Fixes this monotouch-test failure with CoreCLR: [FAIL] Tamarin : System.Runtime.InteropServices.MarshalDirectiveException : Cannot marshal 'parameter #3': Non-blittable generic types cannot be marshaled. at CoreGraphics.CGPDFOperatorTable.CGPDFOperatorTableSetCallback(IntPtr table, String name, Action`2 callback) at CoreGraphics.CGPDFOperatorTable.SetCallback(String name, Action`2 callback) at MonoTouchFixtures.CoreGraphics.PDFScannerTest.Tamarin() in xamarin-macios/tests/monotouch-test/CoreGraphics/PDFScannerTest.cs:line 102 Ref: dotnet/runtime#32963
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
// this won't work with AOT since the callback must be decorated with [MonoPInvokeCallback] | ||
public void SetCallback (string name, Action<CGPDFScanner,object> callback) | ||
{ | ||
if (name == null) | ||
throw new ArgumentNullException ("name"); | ||
|
||
if (callback == null) | ||
CGPDFOperatorTableSetCallback (Handle, name, null); | ||
CGPDFOperatorTableSetCallback (Handle, name, (CGPDFOperatorCallback) null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah I don't recall seeing this before haha. A type cast for null! What does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tj-devel709 imaging you are a compiler and you see:
public void CGPDFOperatorTableSetCallback (IntPtr handel, String name, CGPDFOperatorCallback callback) {...}
public void CGPDFOperatorTableSetCallback (IntPtr handel, String name, OtherObject obj) {..}
Later in the code I have:
CGPDFOperatorTableSetCallback (Handle, name, null);
Which of the above overloads do you call??
And if you see:
CGPDFOperatorTableSetCallback (Handle, name, (CGPDFOperatorCallback) null);
AFAIK you can also do:
CGPDFOperatorTableSetCallback (Handle, name, default(CGPDFOperatorCallback));
which helps the compiler too without a cast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thank you for explaining!
✅ [PR Build] Tests passed on Build. ✅Tests passed on Build. API diff✅ API Diff from stable View API diffAPI & Generator diff✅ API Diff (from PR only) (no change) 🎉 All 82 tests passed 🎉Pipeline on Agent XAMBOT-1104.BigSur' |
we need to find a different solution.
because we can't pass it callback-specific data, which means that the
managed caller must conform to the FullAOT requirement of the managed
callback (must be a static function; must have a MonoPInvokeCallback
attribute).
requirements enforced by the C# compiler (unmanaged function pointer +
UnmanagedCallersOnly attribute). The resulting API is still clunky to use,
but I don't see any way around that.
Fixes this monotouch-test failure with CoreCLR:
Ref: dotnet/runtime#32963