diff --git a/src/Core/Silk.NET.Core/Miscellaneous/PfnVoidFunction.cs b/src/Core/Silk.NET.Core/Miscellaneous/PfnVoidFunction.cs index a4634db0fe..ebcc681836 100644 --- a/src/Core/Silk.NET.Core/Miscellaneous/PfnVoidFunction.cs +++ b/src/Core/Silk.NET.Core/Miscellaneous/PfnVoidFunction.cs @@ -13,8 +13,7 @@ namespace Silk.NET.Core public static implicit operator nint(PfnVoidFunction pfn) => (nint) pfn.Handle; public PfnVoidFunction - (Delegate func) => _handle = (delegate* unmanaged[Cdecl]) SilkMarshal.DelegateToPtr - (func); + (Delegate func) => _handle = (delegate* unmanaged[Cdecl]) SilkMarshal.DelegateToPtr(func); public void Dispose() => SilkMarshal.Free((nint) _handle); public static implicit operator delegate* unmanaged[Cdecl] @@ -25,4 +24,4 @@ public static implicit operator PfnVoidFunction public static implicit operator PfnVoidFunction(Delegate func) => new(func); } -} \ No newline at end of file +} diff --git a/src/Core/Silk.NET.Core/Native/SilkMarshal.cs b/src/Core/Silk.NET.Core/Native/SilkMarshal.cs index 9d6b9be839..8b40d79c3c 100644 --- a/src/Core/Silk.NET.Core/Native/SilkMarshal.cs +++ b/src/Core/Silk.NET.Core/Native/SilkMarshal.cs @@ -716,6 +716,32 @@ public static nint DelegateToPtr static void ThrowManagedNonStatic() => throw new InvalidOperationException("Can't get a passthrough pointer to a non-static method group."); } + + /// + /// Gets a function pointer for the given delegate. + /// + /// The delegate to get a function pointer to. + /// + /// Whether to pin the delegate such that the returned pointer remains valid for long periods of time. + /// + /// The delegate's type to marshal. + /// A function pointer to the given delegate. + public static nint DelegateToPtr + ( + TDelegate @delegate, + bool pinned = true + ) where TDelegate : notnull + { + if (pinned) + { + var gcHandle = GCHandle.Alloc(@delegate); + var ret = Marshal.GetFunctionPointerForDelegate(@delegate); + _otherGCHandles.TryAdd(ret, gcHandle); + return ret; + } + + return Marshal.GetFunctionPointerForDelegate(@delegate); + } private static void DelegateSafetyCheck(Delegate @delegate, CallingConvention conv) {