[.NET/CoreGraphics] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCallback] Partial Fix for #10470 (#15906)

Completed the work for CoreGraphics.
One exception is PDFArray.cs which uses `SetupBlockUnsafe` (noted in the
issue)

Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
This commit is contained in:
Steve Hawley 2022-09-12 09:46:01 -04:00 коммит произвёл GitHub
Родитель 1552a1e20b
Коммит 2a37989a4b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 97 добавлений и 3 удалений

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

@ -144,29 +144,48 @@ namespace CoreGraphics {
{
}
#if NET
[DllImport (Constants.CoreGraphicsLibrary)]
extern static unsafe IntPtr CGDataProviderCreateWithData (/* void* */ IntPtr info, /* const void* */ IntPtr data, /* size_t */ nint size, /* CGDataProviderReleaseDataCallback */ delegate* unmanaged<IntPtr, IntPtr, nint, void> releaseData);
#else
[DllImport (Constants.CoreGraphicsLibrary)]
extern static IntPtr CGDataProviderCreateWithData (/* void* */ IntPtr info, /* const void* */ IntPtr data, /* size_t */ nint size, /* CGDataProviderReleaseDataCallback */ CGDataProviderReleaseDataCallback releaseData);
#endif
#if !NET
delegate void CGDataProviderReleaseDataCallback (IntPtr info, IntPtr data, nint size);
static CGDataProviderReleaseDataCallback release_gchandle_callback = ReleaseGCHandle;
static CGDataProviderReleaseDataCallback release_buffer_callback = ReleaseBuffer;
static CGDataProviderReleaseDataCallback release_func_callback = ReleaseFunc;
#endif
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CGDataProviderReleaseDataCallback))]
#endif
private static void ReleaseGCHandle (IntPtr info, IntPtr data, nint size)
{
var gch = GCHandle.FromIntPtr (info);
gch.Free ();
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CGDataProviderReleaseDataCallback))]
#endif
private static void ReleaseBuffer (IntPtr info, IntPtr data, nint size)
{
if (data != IntPtr.Zero)
Marshal.FreeHGlobal (data);
}
#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof (CGDataProviderReleaseDataCallback))]
#endif
private static void ReleaseFunc (IntPtr info, IntPtr data, nint size)
{
var gch = GCHandle.FromIntPtr (info);
@ -188,7 +207,13 @@ namespace CoreGraphics {
{
if (!ownBuffer)
memoryBlock = Runtime.CloneMemory (memoryBlock, size);
#if NET
unsafe {
return CGDataProviderCreateWithData (IntPtr.Zero, memoryBlock, size, &ReleaseBuffer);
}
#else
return CGDataProviderCreateWithData (IntPtr.Zero, memoryBlock, size, release_buffer_callback);
#endif
}
public CGDataProvider (IntPtr memoryBlock, int size, bool ownBuffer)
@ -202,7 +227,13 @@ namespace CoreGraphics {
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (releaseMemoryBlockCallback));
var gch = GCHandle.Alloc (releaseMemoryBlockCallback);
#if NET
unsafe {
return CGDataProviderCreateWithData (GCHandle.ToIntPtr (gch), memoryBlock, size, &ReleaseFunc);
}
#else
return CGDataProviderCreateWithData (GCHandle.ToIntPtr (gch), memoryBlock, size, release_func_callback);
#endif
}
public CGDataProvider (IntPtr memoryBlock, int size, Action<IntPtr> releaseMemoryBlockCallback)
@ -221,7 +252,13 @@ namespace CoreGraphics {
var gch = GCHandle.Alloc (buffer, GCHandleType.Pinned); // This requires a pinned GCHandle, because unsafe code is scoped to the current block, and the address of the byte array will be used after this function returns.
var ptr = gch.AddrOfPinnedObject () + offset;
#if NET
unsafe {
return CGDataProviderCreateWithData (GCHandle.ToIntPtr (gch), ptr, count, &ReleaseGCHandle);
}
#else
return CGDataProviderCreateWithData (GCHandle.ToIntPtr (gch), ptr, count, release_gchandle_callback);
#endif
}
public CGDataProvider (byte [] buffer, int offset, int count)

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

@ -58,8 +58,13 @@ namespace CoreGraphics {
unsafe static CGFunction ()
{
cbacks.version = 0;
#if NET
cbacks.evaluate = &EvaluateCallback;
cbacks.release = &ReleaseCallback;
#else
cbacks.evaluate = new CGFunctionEvaluateCallback (EvaluateCallback);
cbacks.release = new CGFunctionReleaseCallback (ReleaseCallback);
#endif
}
#if !NET
@ -107,8 +112,13 @@ namespace CoreGraphics {
[StructLayout (LayoutKind.Sequential)]
struct CGFunctionCallbacks {
public /* unsigned int */ uint version;
#if NET
public unsafe delegate* unmanaged<IntPtr, nfloat*, nfloat*, void> evaluate;
public unsafe delegate* unmanaged<IntPtr, void> release;
#else
public CGFunctionEvaluateCallback? evaluate;
public CGFunctionReleaseCallback? release;
#endif
}
[DllImport (Constants.CoreGraphicsLibrary)]
@ -136,17 +146,24 @@ namespace CoreGraphics {
var handle = CGFunctionCreate (GCHandle.ToIntPtr (gch), domain is not null ? domain.Length / 2 : 0, domain, range is not null ? range.Length / 2 : 0, range, ref cbacks);
InitializeHandle (handle);
}
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (CGFunctionReleaseCallback))]
#endif
#endif
static void ReleaseCallback (IntPtr info)
{
GCHandle.FromIntPtr (info).Free ();
}
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (CGFunctionEvaluateCallback))]
#endif
#endif
unsafe static void EvaluateCallback (IntPtr info, nfloat *input, nfloat *output)
{

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

@ -478,9 +478,12 @@ namespace CoreGraphics {
public delegate void ApplierFunction (CGPathElement element);
delegate void CGPathApplierFunction (/* void* */ IntPtr info, /* const CGPathElement* */ IntPtr element);
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (CGPathApplierFunction))]
#endif
#endif
static void ApplierCallback (IntPtr info, IntPtr element_ptr)
{
@ -520,12 +523,22 @@ namespace CoreGraphics {
[DllImport (Constants.CoreGraphicsLibrary)]
#if NET
extern unsafe static void CGPathApply (/* CGPathRef */ IntPtr path, /* void* */ IntPtr info, delegate* unmanaged<IntPtr, IntPtr, void> function);
#else
extern static void CGPathApply (/* CGPathRef */ IntPtr path, /* void* */ IntPtr info, CGPathApplierFunction function);
#endif
public void Apply (ApplierFunction func)
{
GCHandle gch = GCHandle.Alloc (func);
#if NET
unsafe {
CGPathApply (Handle, GCHandle.ToIntPtr (gch), &ApplierCallback);
}
#else
CGPathApply (Handle, GCHandle.ToIntPtr (gch), ApplierCallback);
#endif
gch.Free ();
}

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

@ -56,8 +56,13 @@ namespace CoreGraphics {
[StructLayout (LayoutKind.Sequential)]
struct CGPatternCallbacks {
internal /* unsigned int */ uint version;
#if NET
internal unsafe delegate* unmanaged<IntPtr, IntPtr, void> draw;
internal unsafe delegate* unmanaged<IntPtr, void> release;
#else
internal DrawPatternCallback draw;
internal ReleaseInfoCallback release;
#endif
}
@ -95,11 +100,25 @@ namespace CoreGraphics {
/* CGFloat */ nfloat xStep, /* CGFloat */ nfloat yStep, CGPatternTiling tiling, [MarshalAs (UnmanagedType.I1)] bool isColored,
/* const CGPatternCallbacks* */ ref CGPatternCallbacks callbacks);
#if NET
static CGPatternCallbacks callbacks;
static CGPattern () {
unsafe {
callbacks = new CGPatternCallbacks () {
version = 0,
draw = &DrawCallback,
release = &ReleaseCallback,
};
}
}
#else
static CGPatternCallbacks callbacks = new CGPatternCallbacks () {
version = 0,
draw = DrawCallback,
release = ReleaseCallback,
};
#endif
GCHandle gch;
public CGPattern (CGRect bounds, CGAffineTransform matrix, nfloat xStep, nfloat yStep, CGPatternTiling tiling, bool isColored, DrawPattern drawPattern)
@ -111,8 +130,12 @@ namespace CoreGraphics {
Handle = CGPatternCreate (GCHandle.ToIntPtr (gch), bounds, matrix, xStep, yStep, tiling, isColored, ref callbacks);
}
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (DrawPatternCallback))]
#endif
#endif
static void DrawCallback (IntPtr voidptr, IntPtr cgcontextptr)
{
@ -123,8 +146,12 @@ namespace CoreGraphics {
}
}
#if NET
[UnmanagedCallersOnly]
#else
#if !MONOMAC
[MonoPInvokeCallback (typeof (ReleaseInfoCallback))]
#endif
#endif
static void ReleaseCallback (IntPtr voidptr)
{