Fix crash in C# JobSystem.Dispatch due to GC collecting Delegate object

This commit is contained in:
Wojtek Figat
2023-09-22 12:50:50 +02:00
parent a0de513a43
commit 62c2008cbc
2 changed files with 15 additions and 1 deletions

View File

@@ -148,6 +148,20 @@ namespace FlaxEngine.Interop
NativeMemory.AlignedFree(ptr);
}
/// <summary>
/// Converts a delegate into a function pointer that is callable from unmanaged code via <see cref="Marshal.GetFunctionPointerForDelegate{TDelegate}"/> but cached <paramref name="d"/> delegate to prevent collecting it by GC.
/// </summary>
/// <typeparam name="TDelegate">The type of delegate to convert.</typeparam>
/// <param name="d">The delegate to be passed to unmanaged code.</param>
/// <returns>A value that can be passed to unmanaged code, which, in turn, can use it to call the underlying managed delegate.</returns>
public static IntPtr GetFunctionPointerForDelegate<TDelegate>(TDelegate d) where TDelegate : notnull
{
// Example use-case: C# script runs actions via JobSystem.Dispatch which causes crash due to GC collecting Delegate object
ManagedHandle.Alloc(d, GCHandleType.Weak);
return Marshal.GetFunctionPointerForDelegate<TDelegate>(d);
}
/// <summary>
/// Converts array of GC Handles from native runtime to managed array.
/// </summary>

View File

@@ -464,7 +464,7 @@ namespace Flax.Build.Bindings
return "FlaxEngine.Object.GetUnmanagedPtr({0})";
case "Function":
// delegate
return "Marshal.GetFunctionPointerForDelegate({0})";
return "NativeInterop.GetFunctionPointerForDelegate({0})";
default:
var apiType = FindApiTypeInfo(buildData, typeInfo, caller);
if (apiType != null)