Skip to content

Commit 7cfc7b3

Browse files
authored
Fix SilkMarshal.DelegateToPtr for NativeAOT (#2428)
* Start fix to DelegateToPtr * add delegatetoptr overload * fix ambiguity error in PfnVoidFunction
1 parent c919502 commit 7cfc7b3

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/Core/Silk.NET.Core/Miscellaneous/PfnVoidFunction.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ namespace Silk.NET.Core
1313
public static implicit operator nint(PfnVoidFunction pfn) => (nint) pfn.Handle;
1414

1515
public PfnVoidFunction
16-
(Delegate func) => _handle = (delegate* unmanaged[Cdecl]<void>) SilkMarshal.DelegateToPtr
17-
(func);
16+
(Delegate func) => _handle = (delegate* unmanaged[Cdecl]<void>) SilkMarshal.DelegateToPtr<Delegate>(func);
1817

1918
public void Dispose() => SilkMarshal.Free((nint) _handle);
2019
public static implicit operator delegate* unmanaged[Cdecl]<void>
@@ -25,4 +24,4 @@ public static implicit operator PfnVoidFunction
2524

2625
public static implicit operator PfnVoidFunction(Delegate func) => new(func);
2726
}
28-
}
27+
}

src/Core/Silk.NET.Core/Native/SilkMarshal.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,32 @@ public static nint DelegateToPtr
716716
static void ThrowManagedNonStatic()
717717
=> throw new InvalidOperationException("Can't get a passthrough pointer to a non-static method group.");
718718
}
719+
720+
/// <summary>
721+
/// Gets a function pointer for the given delegate.
722+
/// </summary>
723+
/// <param name="delegate">The delegate to get a function pointer to.</param>
724+
/// <param name="pinned">
725+
/// Whether to pin the delegate such that the returned pointer remains valid for long periods of time.
726+
/// </param>
727+
/// <typeparam name="TDelegate">The delegate's type to marshal.</typeparam>
728+
/// <returns>A function pointer to the given delegate.</returns>
729+
public static nint DelegateToPtr<TDelegate>
730+
(
731+
TDelegate @delegate,
732+
bool pinned = true
733+
) where TDelegate : notnull
734+
{
735+
if (pinned)
736+
{
737+
var gcHandle = GCHandle.Alloc(@delegate);
738+
var ret = Marshal.GetFunctionPointerForDelegate<TDelegate>(@delegate);
739+
_otherGCHandles.TryAdd(ret, gcHandle);
740+
return ret;
741+
}
742+
743+
return Marshal.GetFunctionPointerForDelegate<TDelegate>(@delegate);
744+
}
719745

720746
private static void DelegateSafetyCheck(Delegate @delegate, CallingConvention conv)
721747
{

0 commit comments

Comments
 (0)