Fix incorrect result array memory copy from native to managed code

This commit is contained in:
Wojtek Figat
2025-04-04 00:36:35 +02:00
parent 9c0c809e7e
commit 210c8e8fe4
2 changed files with 23 additions and 2 deletions

View File

@@ -563,7 +563,7 @@ namespace FlaxEngine.Interop
{ {
T[] sourceArray; T[] sourceArray;
ManagedArray managedArray; ManagedArray managedArray;
ManagedHandle handle; ManagedHandle handle; // Valid only for pooled array
public void FromManaged(T[] managed) public void FromManaged(T[] managed)
{ {
@@ -588,7 +588,13 @@ namespace FlaxEngine.Interop
{ {
ManagedArray arr = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target); ManagedArray arr = Unsafe.As<ManagedArray>(ManagedHandle.FromIntPtr(new IntPtr(unmanaged)).Target);
if (sourceArray == null || sourceArray.Length != arr.Length) if (sourceArray == null || sourceArray.Length != arr.Length)
{
// Array was resized when returned from native code (as ref parameter)
managedArray.FreePooled();
sourceArray = new T[arr.Length]; sourceArray = new T[arr.Length];
managedArray = arr;
handle = new ManagedHandle(); // Invalidate as it's not pooled array anymore
}
} }
public ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(int numElements) public ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(int numElements)
@@ -602,7 +608,11 @@ namespace FlaxEngine.Interop
public T[] ToManaged() => sourceArray; public T[] ToManaged() => sourceArray;
public void Free() => managedArray.FreePooled(); public void Free()
{
if (handle.IsAllocated)
managedArray.FreePooled();
}
} }
public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[] managed, out int numElements) public static TUnmanagedElement* AllocateContainerForUnmanagedElements(T[] managed, out int numElements)

View File

@@ -1207,6 +1207,7 @@ namespace Flax.Build.Bindings
string callReturnCount = ""; string callReturnCount = "";
if (returnTypeIsContainer) if (returnTypeIsContainer)
{ {
// Array marshallers need to know amount of items written in the buffer
callReturnCount = indent; callReturnCount = indent;
if (returnType.Type == "Span" || returnType.Type == "BytesContainer") if (returnType.Type == "Span" || returnType.Type == "BytesContainer")
callReturnCount += "*__returnCount = {0}.Length();"; callReturnCount += "*__returnCount = {0}.Length();";
@@ -1349,6 +1350,7 @@ namespace Flax.Build.Bindings
#if USE_NETCORE #if USE_NETCORE
if (parameterInfo.Type.Type == "Array") if (parameterInfo.Type.Type == "Array")
{ {
// Array marshallers need to know amount of items written in the buffer
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine(); contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
} }
#endif #endif
@@ -1368,6 +1370,8 @@ namespace Flax.Build.Bindings
if (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null) if (parameterInfo.Type.Type == "BytesContainer" && parameterInfo.Type.GenericArgs == null)
{ {
contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine(); contents.Append(indent).AppendFormat("MCore::GC::WriteRef({0}, (MObject*){1});", parameterInfo.Name, value).AppendLine();
// Array marshallers need to know amount of items written in the buffer
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Length();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine(); contents.Append(indent).AppendFormat("*__{0}Count = {1}.Length();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
continue; continue;
} }
@@ -1376,6 +1380,13 @@ namespace Flax.Build.Bindings
} }
} }
contents.Append(indent).AppendFormat("*{0} = {1};", parameterInfo.Name, value).AppendLine(); contents.Append(indent).AppendFormat("*{0} = {1};", parameterInfo.Name, value).AppendLine();
#if USE_NETCORE
if (parameterInfo.Type.Type == "Array")
{
// Array marshallers need to know amount of items written in the buffer
contents.Append(indent).AppendFormat("*__{0}Count = {1}.Count();", parameterInfo.Name, parameterInfo.Name + "Temp").AppendLine();
}
#endif
} }
} }
} }