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; } } }