diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index bb20ced62..638b58223 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -586,8 +586,17 @@ namespace FlaxEngine.Interop internal static ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle) { Type elementType = Unsafe.As(elementTypeHandle.Target); - Type classType = ArrayFactory.GetArrayType(elementType); - return GetTypeManagedHandle(classType); + Type arrayType = ArrayFactory.GetArrayType(elementType); + return GetTypeManagedHandle(arrayType); + } + + [UnmanagedCallersOnly] + internal static ManagedHandle GetArrayTypeFromWrappedArray(ManagedHandle arrayHandle) + { + ManagedArray managedArray = Unsafe.As(arrayHandle.Target); + Type elementType = managedArray.ArrayType.GetElementType(); + Type arrayType = ArrayFactory.GetArrayType(elementType); + return GetTypeManagedHandle(arrayType); } [UnmanagedCallersOnly] diff --git a/Source/Engine/Scripting/Internal/StdTypesContainer.cpp b/Source/Engine/Scripting/Internal/StdTypesContainer.cpp index 817c86a57..e1ff23ee2 100644 --- a/Source/Engine/Scripting/Internal/StdTypesContainer.cpp +++ b/Source/Engine/Scripting/Internal/StdTypesContainer.cpp @@ -40,6 +40,8 @@ void StdTypesContainer::Clear() Json_SerializeDiff = nullptr; Json_Deserialize = nullptr; + ManagedArrayClass = nullptr; + #if USE_EDITOR ExecuteInEditModeAttribute = nullptr; #endif @@ -88,6 +90,8 @@ bool StdTypesContainer::Gather() GET_METHOD(Json_SerializeDiff, JSON, "SerializeDiff", 3); GET_METHOD(Json_Deserialize, JSON, "Deserialize", 3); + GET_CLASS(FlaxEngine, ManagedArrayClass, "FlaxEngine.Interop.ManagedArray"); + #if USE_EDITOR GET_CLASS(FlaxEngine, ExecuteInEditModeAttribute, "FlaxEngine.ExecuteInEditModeAttribute"); #endif diff --git a/Source/Engine/Scripting/Internal/StdTypesContainer.h b/Source/Engine/Scripting/Internal/StdTypesContainer.h index 62231a689..94ea73675 100644 --- a/Source/Engine/Scripting/Internal/StdTypesContainer.h +++ b/Source/Engine/Scripting/Internal/StdTypesContainer.h @@ -45,6 +45,8 @@ public: MMethod* Json_SerializeDiff; MMethod* Json_Deserialize; + MClass* ManagedArrayClass; + #if USE_EDITOR MClass* ExecuteInEditModeAttribute; #endif diff --git a/Source/Engine/Scripting/ManagedCLR/MCore.h b/Source/Engine/Scripting/ManagedCLR/MCore.h index 5352a4b29..35227df56 100644 --- a/Source/Engine/Scripting/ManagedCLR/MCore.h +++ b/Source/Engine/Scripting/ManagedCLR/MCore.h @@ -83,6 +83,7 @@ public: { static MArray* New(const MClass* elementKlass, int32 length); static MClass* GetClass(MClass* elementKlass); + static MClass* GetArrayClass(const MArray* obj); static int32 GetLength(const MArray* obj); static void* GetAddress(const MArray* obj); static MArray* Unbox(MObject* obj); diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp index c0c3cdc45..810abbe48 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.cpp +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.cpp @@ -394,14 +394,15 @@ Variant MUtils::UnboxVariant(MObject* value) case MTypes::Array: { void* ptr = MCore::Array::GetAddress((MArray*)value); - MClass* elementClass = klass->GetElementClass(); + const MClass* arrayClass = klass == stdTypes.ManagedArrayClass ? MCore::Array::GetArrayClass((MArray*)value) : klass; + const MClass* elementClass = arrayClass->GetElementClass(); if (elementClass == MCore::TypeCache::Byte) { Variant v; v.SetBlob(ptr, MCore::Array::GetLength((MArray*)value)); return v; } - const StringAnsiView fullname = klass->GetFullName(); + const StringAnsiView fullname = arrayClass->GetFullName(); Variant v; v.SetType(MoveTemp(VariantType(VariantType::Array, fullname))); auto& array = v.AsArray(); diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 01b43c049..a3ec1321f 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -402,8 +402,15 @@ MArray* MCore::Array::New(const MClass* elementKlass, int32 length) MClass* MCore::Array::GetClass(MClass* elementKlass) { - static void* GetArrayLengthPtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType")); - MType* typeHandle = (MType*)CallStaticMethod(GetArrayLengthPtr, elementKlass->_handle); + static void* GetArrayTypeFromElementTypePtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromElementType")); + MType* typeHandle = (MType*)CallStaticMethod(GetArrayTypeFromElementTypePtr, elementKlass->_handle); + return GetOrCreateClass(typeHandle); +} + +MClass* MCore::Array::GetArrayClass(const MArray* obj) +{ + static void* GetArrayTypeFromWrappedArrayPtr = GetStaticMethodPointer(TEXT("GetArrayTypeFromWrappedArray")); + MType* typeHandle = (MType*)CallStaticMethod(GetArrayTypeFromWrappedArrayPtr, (void*)obj); return GetOrCreateClass(typeHandle); } diff --git a/Source/Engine/Scripting/Runtime/Mono.cpp b/Source/Engine/Scripting/Runtime/Mono.cpp index 2e507a44a..40fa8f4bf 100644 --- a/Source/Engine/Scripting/Runtime/Mono.cpp +++ b/Source/Engine/Scripting/Runtime/Mono.cpp @@ -795,6 +795,12 @@ MClass* MCore::Array::GetClass(MClass* elementKlass) return FindClass(monoClass); } +MClass* MCore::Array::GetArrayClass(const MArray* obj) +{ + CRASH; // Not applicable + return nullptr; +} + int32 MCore::Array::GetLength(const MArray* obj) { return (int32)mono_array_length((MonoArray*)obj); diff --git a/Source/Engine/Scripting/Runtime/None.cpp b/Source/Engine/Scripting/Runtime/None.cpp index 1fb0e6d1f..bb83fd27d 100644 --- a/Source/Engine/Scripting/Runtime/None.cpp +++ b/Source/Engine/Scripting/Runtime/None.cpp @@ -130,6 +130,11 @@ MClass* MCore::Array::GetClass(MClass* elementKlass) return nullptr; } +MClass* MCore::Array::GetArrayClass(const MArray* obj) +{ + return nullptr; +} + int32 MCore::Array::GetLength(const MArray* obj) { return 0;