CPF/CPF.Mac/Mac/ObjCRuntime/BlockLiteral.cs

52 lines
1.2 KiB
C#
Raw Normal View History

2023-11-21 23:05:03 +08:00
using System;
using System.Runtime.InteropServices;
namespace CPF.Mac.ObjCRuntime
{
public struct BlockLiteral
{
public IntPtr isa;
public BlockFlags flags;
public int reserved;
public IntPtr invoke;
public IntPtr block_descriptor;
public IntPtr local_handle;
public IntPtr global_handle;
internal static IntPtr block_class;
internal static BlockDescriptor global_descriptor;
internal static IntPtr global_descriptor_ptr;
static BlockLiteral()
{
block_class = Class.GetHandle("__NSStackBlock");
global_descriptor = BlockDescriptor.CreateDescriptor();
global_descriptor_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * 2 + Marshal.SizeOf(typeof(IntPtr)) * 2);
Marshal.StructureToPtr(global_descriptor, global_descriptor_ptr, fDeleteOld: false);
}
public void SetupBlock(Delegate trampoline, Delegate userDelegate)
{
isa = block_class;
invoke = Marshal.GetFunctionPointerForDelegate(trampoline);
local_handle = (IntPtr)GCHandle.Alloc(userDelegate);
global_handle = IntPtr.Zero;
flags = (BlockFlags.BLOCK_HAS_COPY_DISPOSE | BlockFlags.BLOCK_HAS_DESCRIPTOR);
block_descriptor = global_descriptor_ptr;
}
public void CleanupBlock()
{
GCHandle.FromIntPtr(local_handle).Free();
}
}
}