[.NET/CoreFoundation] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCallback] for the CGPDFDictionaryApplyFunction function. (#12956)

I had to change the first argument from 'string' to 'IntPtr', because 'string'
isn't blittable. In order to diverge the code paths as little as possible, I
also made this change for the legacy Xamarin version.

Ref https://github.com/xamarin/xamarin-macios/issues/10470.
This commit is contained in:
Rolf Bjarne Kvinge 2021-10-08 07:53:43 +02:00 коммит произвёл GitHub
Родитель 6d8ef62705
Коммит 7a46df3dbd
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 31 добавлений и 5 удалений

Просмотреть файл

@ -154,24 +154,34 @@ namespace CoreGraphics {
return r; return r;
} }
#if NET
[DllImport (Constants.CoreGraphicsLibrary)]
unsafe extern static void CGPDFDictionaryApplyFunction (/* CGPDFDictionaryRef */ IntPtr dic, delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> function, /* void* */ IntPtr info);
#else
// CGPDFDictionaryApplierFunction // CGPDFDictionaryApplierFunction
delegate void ApplierFunction (/* const char* */ string key, /* CGPDFObjectRef */ IntPtr value, /* void* */ IntPtr info); delegate void ApplierFunction (/* const char* */ IntPtr key, /* CGPDFObjectRef */ IntPtr value, /* void* */ IntPtr info);
[DllImport (Constants.CoreGraphicsLibrary)] [DllImport (Constants.CoreGraphicsLibrary)]
extern static void CGPDFDictionaryApplyFunction (/* CGPDFDictionaryRef */ IntPtr dic, ApplierFunction function, /* void* */ IntPtr info); extern static void CGPDFDictionaryApplyFunction (/* CGPDFDictionaryRef */ IntPtr dic, ApplierFunction function, /* void* */ IntPtr info);
static readonly ApplierFunction applyblock_handler = ApplyBridge; static readonly ApplierFunction applyblock_handler = ApplyBridge;
#endif // NET
public delegate void ApplyCallback (string key, object value, object info); public delegate void ApplyCallback (string key, object value, object info);
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC #if !MONOMAC
[MonoPInvokeCallback (typeof (ApplierFunction))] [MonoPInvokeCallback (typeof (ApplierFunction))]
#endif #endif
static void ApplyBridge (string key, IntPtr pdfObject, IntPtr info) #endif // NET
static void ApplyBridge (IntPtr key, IntPtr pdfObject, IntPtr info)
{ {
var data = (Tuple<ApplyCallback, object>) GCHandle.FromIntPtr (info).Target; var data = (Tuple<ApplyCallback, object>) GCHandle.FromIntPtr (info).Target;
var callback = data.Item1; var callback = data.Item1;
callback (key, CGPDFObject.FromHandle (pdfObject), data.Item2); callback (Marshal.PtrToStringUTF8 (key), CGPDFObject.FromHandle (pdfObject), data.Item2);
} }
public void Apply (ApplyCallback callback, object info = null) public void Apply (ApplyCallback callback, object info = null)
@ -179,26 +189,42 @@ namespace CoreGraphics {
var data = new Tuple<ApplyCallback, object> (callback, info); var data = new Tuple<ApplyCallback, object> (callback, info);
var gch = GCHandle.Alloc (data); var gch = GCHandle.Alloc (data);
try { try {
#if NET
unsafe {
CGPDFDictionaryApplyFunction (Handle, &ApplyBridge, GCHandle.ToIntPtr (gch));
}
#else
CGPDFDictionaryApplyFunction (Handle, applyblock_handler, GCHandle.ToIntPtr (gch)); CGPDFDictionaryApplyFunction (Handle, applyblock_handler, GCHandle.ToIntPtr (gch));
#endif
} finally { } finally {
gch.Free (); gch.Free ();
} }
} }
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC #if !MONOMAC
[MonoPInvokeCallback (typeof (ApplierFunction))] [MonoPInvokeCallback (typeof (ApplierFunction))]
#endif #endif
static void ApplyBridge2 (string key, IntPtr pdfObject, IntPtr info) #endif // NET
static void ApplyBridge2 (IntPtr key, IntPtr pdfObject, IntPtr info)
{ {
var callback = (Action<string,CGPDFObject>) GCHandle.FromIntPtr (info).Target; var callback = (Action<string,CGPDFObject>) GCHandle.FromIntPtr (info).Target;
callback (key, new CGPDFObject (pdfObject)); callback (Marshal.PtrToStringUTF8 (key), new CGPDFObject (pdfObject));
} }
public void Apply (Action<string,CGPDFObject> callback) public void Apply (Action<string,CGPDFObject> callback)
{ {
GCHandle gch = GCHandle.Alloc (callback); GCHandle gch = GCHandle.Alloc (callback);
#if NET
unsafe {
CGPDFDictionaryApplyFunction (Handle, &ApplyBridge2, GCHandle.ToIntPtr (gch));
}
#else
CGPDFDictionaryApplyFunction (Handle, ApplyBridge2, GCHandle.ToIntPtr (gch)); CGPDFDictionaryApplyFunction (Handle, ApplyBridge2, GCHandle.ToIntPtr (gch));
#endif
gch.Free (); gch.Free ();
} }