Fix using managed arrays with Variant in dotnet7
This commit is contained in:
@@ -391,8 +391,8 @@ namespace FlaxEditor.Content.Import
|
||||
MaxSize = managed.MaxSize,
|
||||
TextureGroup = managed.TextureGroup,
|
||||
Size = managed.Size,
|
||||
SpriteAreas = managed.SpriteAreas?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteAreas))) : IntPtr.Zero,
|
||||
SpriteNames = managed.SpriteNames?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteNames))) : IntPtr.Zero,
|
||||
SpriteAreas = managed.SpriteAreas?.Length > 0 ? ManagedHandle.ToIntPtr(NativeInterop.ManagedArrayToGCHandleWrappedArray(managed.SpriteAreas)) : IntPtr.Zero,
|
||||
SpriteNames = managed.SpriteNames?.Length > 0 ? ManagedHandle.ToIntPtr(NativeInterop.ManagedArrayToGCHandleWrappedArray(managed.SpriteNames)) : IntPtr.Zero,
|
||||
};
|
||||
}
|
||||
internal static void Free(InternalOptionsNative unmanaged)
|
||||
|
||||
@@ -157,39 +157,49 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
public unsafe class ManagedArray
|
||||
{
|
||||
private ManagedHandle pinnedArrayHandle;
|
||||
private IntPtr unmanagedData;
|
||||
private Type elementType;
|
||||
private int elementSize;
|
||||
private int length;
|
||||
private ManagedHandle _pinnedArrayHandle;
|
||||
private IntPtr _unmanagedData;
|
||||
private Type _arrayType;
|
||||
private Type _elementType;
|
||||
private int _elementSize;
|
||||
private int _length;
|
||||
|
||||
public static ManagedArray WrapNewArray(Array arr) => new ManagedArray(arr);
|
||||
public static ManagedArray WrapNewArray(Array arr) => new ManagedArray(arr, arr.GetType());
|
||||
|
||||
public static ManagedArray WrapNewArray(Array arr, Type arrayType) => new ManagedArray(arr, arrayType);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of ManagedArray from shared pool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The resources must be released by calling FreePooled() instead of Free()-method.
|
||||
/// </remarks>
|
||||
/// <remarks>The resources must be released by calling FreePooled() instead of Free()-method.</remarks>
|
||||
public static ManagedArray WrapPooledArray(Array arr)
|
||||
{
|
||||
ManagedArray managedArray = ManagedArrayPool.Get();
|
||||
managedArray.WrapArray(arr);
|
||||
managedArray.WrapArray(arr, arr.GetType());
|
||||
return managedArray;
|
||||
}
|
||||
|
||||
internal static ManagedArray AllocateNewArray(int length, Type elementType)
|
||||
=> new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, Marshal.SizeOf(elementType)), length, elementType);
|
||||
|
||||
internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, Type elementType)
|
||||
=> new ManagedArray(ptr, length, elementType);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of ManagedArray from shared pool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The resources must be released by calling FreePooled() instead of Free()-method.
|
||||
/// </remarks>
|
||||
/// <remarks>The resources must be released by calling FreePooled() instead of Free()-method.</remarks>
|
||||
public static ManagedArray WrapPooledArray(Array arr, Type arrayType)
|
||||
{
|
||||
ManagedArray managedArray = ManagedArrayPool.Get();
|
||||
managedArray.WrapArray(arr, arrayType);
|
||||
return managedArray;
|
||||
}
|
||||
|
||||
internal static ManagedArray AllocateNewArray(int length, Type arrayType, Type elementType)
|
||||
=> new ManagedArray((IntPtr)NativeInterop.NativeAlloc(length, Marshal.SizeOf(elementType)), length, arrayType, elementType);
|
||||
|
||||
internal static ManagedArray AllocateNewArray(IntPtr ptr, int length, Type arrayType, Type elementType)
|
||||
=> new ManagedArray(ptr, length, arrayType, elementType);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an instance of ManagedArray from shared pool.
|
||||
/// </summary>
|
||||
/// <remarks>The resources must be released by calling FreePooled() instead of Free()-method.</remarks>
|
||||
public static ManagedArray AllocatePooledArray<T>(T* ptr, int length) where T : unmanaged
|
||||
{
|
||||
ManagedArray managedArray = ManagedArrayPool.Get();
|
||||
@@ -200,67 +210,67 @@ namespace FlaxEngine
|
||||
/// <summary>
|
||||
/// Returns an instance of ManagedArray from shared pool.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The resources must be released by calling FreePooled() instead of Free()-method.
|
||||
/// </remarks>
|
||||
/// <remarks>The resources must be released by calling FreePooled() instead of Free()-method.</remarks>
|
||||
public static ManagedArray AllocatePooledArray<T>(int length) where T : unmanaged
|
||||
{
|
||||
ManagedArray managedArray = ManagedArrayPool.Get();
|
||||
managedArray.Allocate((IntPtr)NativeInterop.NativeAlloc(length, Unsafe.SizeOf<T>()), length, typeof(T));
|
||||
managedArray.Allocate((T*)NativeInterop.NativeAlloc(length, Unsafe.SizeOf<T>()), length);
|
||||
return managedArray;
|
||||
}
|
||||
|
||||
public ManagedArray(Array arr) => WrapArray(arr);
|
||||
public ManagedArray(Array arr, Type elementType) => WrapArray(arr, elementType);
|
||||
|
||||
internal void WrapArray(Array arr)
|
||||
internal void WrapArray(Array arr, Type arrayType)
|
||||
{
|
||||
pinnedArrayHandle = ManagedHandle.Alloc(arr, GCHandleType.Pinned);
|
||||
unmanagedData = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0);
|
||||
length = arr.Length;
|
||||
elementType = arr.GetType().GetElementType();
|
||||
elementSize = Marshal.SizeOf(elementType);
|
||||
_pinnedArrayHandle = ManagedHandle.Alloc(arr, GCHandleType.Pinned);
|
||||
_unmanagedData = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0);
|
||||
_length = arr.Length;
|
||||
_arrayType = arrayType;
|
||||
_elementType = arr.GetType().GetElementType();
|
||||
_elementSize = Marshal.SizeOf(_elementType);
|
||||
}
|
||||
|
||||
internal void Allocate<T>(T* ptr, int length) where T : unmanaged
|
||||
{
|
||||
unmanagedData = new IntPtr(ptr);
|
||||
this.length = length;
|
||||
elementType = typeof(T);
|
||||
elementSize = Unsafe.SizeOf<T>();
|
||||
}
|
||||
|
||||
internal void Allocate(IntPtr ptr, int length, Type elementType)
|
||||
{
|
||||
unmanagedData = ptr;
|
||||
this.length = length;
|
||||
this.elementType = elementType;
|
||||
elementSize = Marshal.SizeOf(elementType);
|
||||
_unmanagedData = new IntPtr(ptr);
|
||||
_length = length;
|
||||
_arrayType = typeof(T).MakeArrayType();
|
||||
_elementType = typeof(T);
|
||||
_elementSize = Unsafe.SizeOf<T>();
|
||||
}
|
||||
|
||||
private ManagedArray()
|
||||
{
|
||||
}
|
||||
|
||||
private ManagedArray(IntPtr ptr, int length, Type elementType) => Allocate(ptr, length, elementType);
|
||||
private ManagedArray(IntPtr ptr, int length, Type arrayType, Type elementType)
|
||||
{
|
||||
Assert.IsTrue(arrayType.IsArray);
|
||||
_unmanagedData = ptr;
|
||||
_length = length;
|
||||
_arrayType = arrayType;
|
||||
_elementType = elementType;
|
||||
_elementSize = Marshal.SizeOf(elementType);
|
||||
}
|
||||
|
||||
~ManagedArray()
|
||||
{
|
||||
if (unmanagedData != IntPtr.Zero)
|
||||
if (_unmanagedData != IntPtr.Zero)
|
||||
Free();
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
if (pinnedArrayHandle.IsAllocated)
|
||||
if (_pinnedArrayHandle.IsAllocated)
|
||||
{
|
||||
pinnedArrayHandle.Free();
|
||||
unmanagedData = IntPtr.Zero;
|
||||
_pinnedArrayHandle.Free();
|
||||
_unmanagedData = IntPtr.Zero;
|
||||
}
|
||||
if (unmanagedData != IntPtr.Zero)
|
||||
if (_unmanagedData != IntPtr.Zero)
|
||||
{
|
||||
NativeInterop.NativeFree(unmanagedData.ToPointer());
|
||||
unmanagedData = IntPtr.Zero;
|
||||
NativeInterop.NativeFree(_unmanagedData.ToPointer());
|
||||
_unmanagedData = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,17 +280,21 @@ namespace FlaxEngine
|
||||
ManagedArrayPool.Put(this);
|
||||
}
|
||||
|
||||
internal IntPtr Pointer => unmanagedData;
|
||||
internal IntPtr Pointer => _unmanagedData;
|
||||
|
||||
internal int Length => length;
|
||||
internal int Length => _length;
|
||||
|
||||
internal int ElementSize => elementSize;
|
||||
internal int ElementSize => _elementSize;
|
||||
|
||||
public Span<T> ToSpan<T>() where T : struct => new Span<T>(unmanagedData.ToPointer(), length);
|
||||
internal Type ElementType => _elementType;
|
||||
|
||||
public T[] ToArray<T>() where T : struct => new Span<T>(unmanagedData.ToPointer(), length).ToArray();
|
||||
internal Type ArrayType => _arrayType;
|
||||
|
||||
public Array ToArray() => ArrayCast.ToArray(new Span<byte>(unmanagedData.ToPointer(), length * elementSize), elementType);
|
||||
public Span<T> ToSpan<T>() where T : struct => new Span<T>(_unmanagedData.ToPointer(), _length);
|
||||
|
||||
public T[] ToArray<T>() where T : struct => new Span<T>(_unmanagedData.ToPointer(), _length).ToArray();
|
||||
|
||||
public Array ToArray() => ArrayCast.ToArray(new Span<byte>(_unmanagedData.ToPointer(), _length * _elementSize), _elementType);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an Array of the specified type from span of bytes.
|
||||
@@ -1251,6 +1265,8 @@ namespace FlaxEngine
|
||||
|
||||
internal static IntPtr[] ManagedArrayToGCHandleArray(Array array)
|
||||
{
|
||||
if (array.Length == 0)
|
||||
return Array.Empty<IntPtr>();
|
||||
IntPtr[] pointerArray = new IntPtr[array.Length];
|
||||
for (int i = 0; i < pointerArray.Length; i++)
|
||||
{
|
||||
@@ -1261,6 +1277,12 @@ namespace FlaxEngine
|
||||
return pointerArray;
|
||||
}
|
||||
|
||||
internal static ManagedArray ManagedArrayToGCHandleWrappedArray(Array array)
|
||||
{
|
||||
IntPtr[] pointerArray = ManagedArrayToGCHandleArray(array);
|
||||
return ManagedArray.WrapNewArray(pointerArray, array.GetType());
|
||||
}
|
||||
|
||||
internal static T[] NativeArrayToManagedArray<T, U>(Span<U> nativeSpan, Func<U, T> toManagedFunc)
|
||||
{
|
||||
T[] managedArray = new T[nativeSpan.Length];
|
||||
@@ -1877,11 +1899,11 @@ namespace FlaxEngine
|
||||
var marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
ManagedArray managedArray;
|
||||
if (marshalledType == elementType)
|
||||
managedArray = ManagedArray.WrapNewArray(arr);
|
||||
managedArray = ManagedArray.WrapNewArray(arr, type);
|
||||
else if (elementType.IsValueType)
|
||||
{
|
||||
// Convert array of custom structures into internal native layout
|
||||
managedArray = ManagedArray.AllocateNewArray(arr.Length, marshalledType);
|
||||
managedArray = ManagedArray.AllocateNewArray(arr.Length, type, marshalledType);
|
||||
IntPtr managedArrayPtr = managedArray.Pointer;
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
@@ -1890,7 +1912,7 @@ namespace FlaxEngine
|
||||
}
|
||||
}
|
||||
else
|
||||
managedArray = ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(arr));
|
||||
managedArray = ManagedArrayToGCHandleWrappedArray(arr);
|
||||
managedPtr = ManagedHandle.ToIntPtr(managedArray, GCHandleType.Weak);
|
||||
}
|
||||
}
|
||||
@@ -2325,21 +2347,30 @@ namespace FlaxEngine
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle NewArray(ManagedHandle typeHandle, long size)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type marshalledType = ArrayFactory.GetMarshalledType(type);
|
||||
Type elementType = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
Type arrayType = elementType.MakeArrayType();
|
||||
if (marshalledType.IsValueType)
|
||||
{
|
||||
ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, marshalledType);
|
||||
ManagedArray managedArray = ManagedArray.AllocateNewArray((int)size, arrayType, marshalledType);
|
||||
return ManagedHandle.Alloc(managedArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array arr = ArrayFactory.CreateArray(type, size);
|
||||
ManagedArray managedArray = ManagedArray.WrapNewArray(arr);
|
||||
Array arr = ArrayFactory.CreateArray(elementType, size);
|
||||
ManagedArray managedArray = ManagedArray.WrapNewArray(arr, arrayType);
|
||||
return ManagedHandle.Alloc(managedArray);
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static unsafe ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle)
|
||||
{
|
||||
Type elementType = Unsafe.As<Type>(elementTypeHandle.Target);
|
||||
Type classType = elementType.MakeArrayType();
|
||||
return GetTypeGCHandle(classType);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static unsafe IntPtr GetArrayPointer(ManagedHandle arrayHandle)
|
||||
{
|
||||
@@ -2392,8 +2423,10 @@ namespace FlaxEngine
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetObjectType(ManagedHandle handle)
|
||||
{
|
||||
var obj = handle.Target;
|
||||
object obj = handle.Target;
|
||||
Type classType = obj.GetType();
|
||||
if (classType == typeof(ManagedArray))
|
||||
classType = ((ManagedArray)obj).ArrayType;
|
||||
return GetTypeGCHandle(classType);
|
||||
}
|
||||
|
||||
@@ -2688,15 +2721,17 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static unsafe int NativeSizeOf(ManagedHandle typeHandle, uint* align)
|
||||
internal static unsafe int NativeSizeOf(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type nativeType = GetInternalType(type) ?? type;
|
||||
if (nativeType == typeof(Version))
|
||||
nativeType = typeof(VersionNative);
|
||||
|
||||
int size = Marshal.SizeOf(nativeType);
|
||||
*align = (uint)size; // Is this correct?
|
||||
int size;
|
||||
if (nativeType.IsClass)
|
||||
size = sizeof(IntPtr);
|
||||
else
|
||||
size = Marshal.SizeOf(nativeType);
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -2927,6 +2962,7 @@ namespace FlaxEngine
|
||||
break;
|
||||
}
|
||||
case Type _ when type.IsArray:
|
||||
case Type _ when type == typeof(ManagedArray):
|
||||
monoType = MTypes.Array;
|
||||
break;
|
||||
case Type _ when type.IsValueType && !type.IsEnum && !type.IsPrimitive:
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace FlaxEngine
|
||||
var elementType = typeof(TRet).GetElementType();
|
||||
if (ArrayFactory.GetMarshalledType(elementType) == elementType)
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnValue)), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<Array>(returnValue))), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArrayToGCHandleWrappedArray(Unsafe.As<Array>(returnValue)), GCHandleType.Weak);
|
||||
}
|
||||
return ManagedHandle.ToIntPtr(returnValue, GCHandleType.Weak);
|
||||
}
|
||||
@@ -108,7 +108,7 @@ namespace FlaxEngine
|
||||
if (returnType.IsArray && ArrayFactory.GetMarshalledType(returnType.GetElementType()) == returnType.GetElementType())
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnObject)), GCHandleType.Weak);
|
||||
if (returnType.IsArray)
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<Array>(returnObject))), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArrayToGCHandleWrappedArray(Unsafe.As<Array>(returnObject)), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(returnObject, GCHandleType.Weak);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace FlaxEngine
|
||||
var elementType = typeof(TRet).GetElementType();
|
||||
if (ArrayFactory.GetMarshalledType(elementType) == elementType)
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnValue)), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<Array>(returnValue))), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArrayToGCHandleWrappedArray(Unsafe.As<Array>(returnValue)), GCHandleType.Weak);
|
||||
}
|
||||
// Match Mono bindings and pass value as pointer to prevent boxing it
|
||||
if (typeof(TRet) == typeof(System.Boolean))
|
||||
@@ -166,7 +166,7 @@ namespace FlaxEngine
|
||||
var elementType = returnType.GetElementType();
|
||||
if (ArrayFactory.GetMarshalledType(elementType) == elementType)
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnObject)), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<Array>(returnObject))), GCHandleType.Weak);
|
||||
return ManagedHandle.ToIntPtr(ManagedArrayToGCHandleWrappedArray(Unsafe.As<Array>(returnObject)), GCHandleType.Weak);
|
||||
}
|
||||
// Match Mono bindings and pass value as pointer to prevent boxing it
|
||||
if (returnType == typeof(System.Boolean))
|
||||
|
||||
@@ -1200,9 +1200,10 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
||||
{
|
||||
// Box instance into C# object
|
||||
MObject* instanceObject = MUtils::BoxVariant(instance);
|
||||
const MClass* instanceObjectClass = MCore::Object::GetClass(instanceObject);
|
||||
|
||||
// Validate instance
|
||||
if (!instanceObject || !MCore::Object::GetClass(instanceObject)->IsSubClassOf(mMethod->GetParentClass(), withInterfaces))
|
||||
if (!instanceObject || !instanceObjectClass->IsSubClassOf(mMethod->GetParentClass(), withInterfaces))
|
||||
{
|
||||
if (!instanceObject)
|
||||
LOG(Error, "Failed to call method '{0}.{1}' (args count: {2}) without object instance", String(mMethod->GetParentClass()->GetFullName()), String(mMethod->GetName()), parametersCount);
|
||||
@@ -1212,7 +1213,7 @@ bool ManagedBinaryModule::InvokeMethod(void* method, const Variant& instance, Sp
|
||||
}
|
||||
|
||||
// For value-types instance is the actual boxed object data, not te object itself
|
||||
mInstance = MCore::Object::GetClass(instanceObject)->IsValueType() ? MCore::Object::Unbox(instanceObject) : instanceObject;
|
||||
mInstance = instanceObjectClass->IsValueType() ? MCore::Object::Unbox(instanceObject) : instanceObject;
|
||||
}
|
||||
|
||||
// Marshal parameters
|
||||
|
||||
@@ -389,7 +389,8 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
case MTypes::Array:
|
||||
{
|
||||
void* ptr = MCore::Array::GetAddress((MArray*)value);
|
||||
if (klass->GetElementClass() == MCore::TypeCache::Byte)
|
||||
MClass* elementClass = klass->GetElementClass();
|
||||
if (elementClass == MCore::TypeCache::Byte)
|
||||
{
|
||||
Variant v;
|
||||
v.SetBlob(ptr, MCore::Array::GetLength((MArray*)value));
|
||||
@@ -401,7 +402,6 @@ Variant MUtils::UnboxVariant(MObject* value)
|
||||
auto& array = v.AsArray();
|
||||
array.Resize(MCore::Array::GetLength((MArray*)value));
|
||||
const StringAnsiView elementTypename(*fullname, fullname.Length() - 2);
|
||||
MClass* elementClass = klass->GetElementClass();
|
||||
const int32 elementSize = elementClass->GetInstanceSize();
|
||||
if (elementClass->IsEnum())
|
||||
{
|
||||
|
||||
@@ -374,8 +374,9 @@ MArray* MCore::Array::New(const MClass* elementKlass, int32 length)
|
||||
|
||||
MClass* MCore::Array::GetClass(MClass* elementKlass)
|
||||
{
|
||||
MISSING_CODE("TODO: MCore::Array::GetClass"); // TODO: MCore::Object::GetClass
|
||||
return nullptr;
|
||||
static void* GetArrayLengthPtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType"));
|
||||
void* classHandle = CallStaticMethod<void*, void*>(GetArrayLengthPtr, elementKlass->_handle);
|
||||
return GetOrCreateClass((void*)classHandle);
|
||||
}
|
||||
|
||||
int32 MCore::Array::GetLength(const MArray* obj)
|
||||
@@ -806,9 +807,8 @@ uint32 MClass::GetInstanceSize() const
|
||||
{
|
||||
if (_size != 0)
|
||||
return _size;
|
||||
uint32 align;
|
||||
static void* NativeSizeOfPtr = GetStaticMethodPointer(TEXT("NativeSizeOf"));
|
||||
_size = CallStaticMethod<int, void*, uint32*>(NativeSizeOfPtr, _handle, &align);
|
||||
_size = CallStaticMethod<int, void*>(NativeSizeOfPtr, _handle);
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
@@ -1541,7 +1541,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
// Array elements passed as GCHandles
|
||||
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null");
|
||||
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak) : IntPtr.Zero");
|
||||
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(NativeInterop.ManagedArrayToGCHandleWrappedArray(managed.{fieldInfo.Name}), GCHandleType.Weak) : IntPtr.Zero");
|
||||
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).ToSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).ToSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user