CPF/CPF.Mac/Mac/ObjCRuntime/BlockDescriptor.cs
2023-11-21 23:05:03 +08:00

50 lines
1.5 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace CPF.Mac.ObjCRuntime
{
public struct BlockDescriptor
{
private unsafe delegate void CopyHelperDelegate(BlockLiteral* dest, BlockLiteral* src);
private unsafe delegate void DisposeHelperDelegate(BlockLiteral* block);
public IntPtr reserved;
public IntPtr size;
public IntPtr copy_helper;
public IntPtr dispose;
private unsafe static CopyHelperDelegate copy_helper_delegate = CopyHelper;
private unsafe static DisposeHelperDelegate dispose_helper_delegate = DisposeHelper;
private unsafe static IntPtr copy_helper_ptr = Marshal.GetFunctionPointerForDelegate(copy_helper_delegate);
private unsafe static IntPtr dispose_helper_ptr = Marshal.GetFunctionPointerForDelegate(dispose_helper_delegate);
[MonoPInvokeCallback(typeof(CopyHelperDelegate))]
private unsafe static void CopyHelper(BlockLiteral* dest, BlockLiteral* source)
{
dest->global_handle = (IntPtr)GCHandle.Alloc(GCHandle.FromIntPtr(dest->local_handle).Target);
}
[MonoPInvokeCallback(typeof(DisposeHelperDelegate))]
private unsafe static void DisposeHelper(BlockLiteral* block)
{
GCHandle.FromIntPtr(block->global_handle).Free();
}
internal static BlockDescriptor CreateDescriptor()
{
BlockDescriptor result = default(BlockDescriptor);
result.copy_helper = copy_helper_ptr;
result.dispose = dispose_helper_ptr;
result.size = (IntPtr)(Marshal.SizeOf(typeof(IntPtr)) * 5 + Marshal.SizeOf(typeof(int)) * 2);
return result;
}
}
}