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 = () => { };
}
}