using System.Runtime.InteropServices; #nullable enable namespace Sandbox; /// /// Helper to wrap while keeping /// a reference to the original delegate, so it won't be garbage collected. /// must be called to remove the reference. /// internal struct DelegateFunctionPointer : IDisposable { public static DelegateFunctionPointer Null => default; private nint _ptr; private Delegate _handle; /// /// Gets the raw function pointer. /// public static implicit operator nint( DelegateFunctionPointer fp ) { return fp._ptr; } /// public static DelegateFunctionPointer Get( T deleg ) where T : Delegate { return new DelegateFunctionPointer( Marshal.GetFunctionPointerForDelegate( deleg ), deleg ); } private DelegateFunctionPointer( nint ptr, Delegate handle ) { _ptr = ptr; _handle = handle; } /// /// Removes the reference to the original delegate, and sets the function pointer to null. /// public void Dispose() { _ptr = nint.Zero; _handle = () => { }; } }