From c79952a4d64c07f2a958499a7908d768d56857f0 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 4 Jul 2023 17:57:59 +0200 Subject: [PATCH] Implement missing dotnet7 interop for field and stabilize interop --- .../Engine/Engine/NativeInterop.Marshallers.cs | 2 +- .../Engine/Engine/NativeInterop.Unmanaged.cs | 18 +++++++++++++++++- Source/Engine/Engine/NativeInterop.cs | 5 ++++- Source/Engine/Scripting/Runtime/DotNet.cpp | 8 ++++---- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Source/Engine/Engine/NativeInterop.Marshallers.cs b/Source/Engine/Engine/NativeInterop.Marshallers.cs index 0a23bfcbd..2e3bc9183 100644 --- a/Source/Engine/Engine/NativeInterop.Marshallers.cs +++ b/Source/Engine/Engine/NativeInterop.Marshallers.cs @@ -399,7 +399,7 @@ namespace FlaxEngine.Interop } numElements = managed.Length; ManagedArray managedArray = ManagedArray.AllocatePooledArray(managed.Length); - return (TUnmanagedElement*)ManagedHandle.ToIntPtr(managedArray, GCHandleType.Weak); + return (TUnmanagedElement*)ManagedHandle.ToIntPtr(managedArray, GCHandleType.Normal); } public static ReadOnlySpan GetManagedValuesSource(T[] managed) => managed; diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index d4a8d44f8..bba9e3db8 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -770,6 +770,13 @@ namespace FlaxEngine.Interop field.field.SetValue(fieldOwner, value); } + [UnmanagedCallersOnly] + internal static int FieldGetOffset(ManagedHandle fieldHandle) + { + FieldHolder field = Unsafe.As(fieldHandle.Target); + return (int)Marshal.OffsetOf(field.field.DeclaringType, field.field.Name); + } + [UnmanagedCallersOnly] internal static void FieldGetValue(ManagedHandle fieldOwnerHandle, ManagedHandle fieldHandle, IntPtr valuePtr) { @@ -778,6 +785,15 @@ namespace FlaxEngine.Interop field.toNativeMarshaller(field.field, fieldOwner, valuePtr, out int fieldOffset); } + [UnmanagedCallersOnly] + internal static IntPtr FieldGetValueBoxed(ManagedHandle fieldOwnerHandle, ManagedHandle fieldHandle) + { + object fieldOwner = fieldOwnerHandle.Target; + FieldHolder field = Unsafe.As(fieldHandle.Target); + object fieldValue = field.field.GetValue(fieldOwner); + return Invoker.MarshalReturnValueGeneric(field.field.FieldType, fieldValue); + } + [UnmanagedCallersOnly] internal static void WriteArrayReference(ManagedHandle arrayHandle, IntPtr valueHandle, int index) { @@ -924,7 +940,7 @@ namespace FlaxEngine.Interop if (nativeType.IsClass) size = sizeof(IntPtr); else - size = Marshal.SizeOf(nativeType); + size = GetTypeSize(type); return size; } diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index e82cb3858..acfd7181b 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -1095,7 +1095,10 @@ namespace FlaxEngine.Interop { try { - size = Marshal.SizeOf(type); + var marshalType = type; + if (type.IsEnum) + marshalType = type.GetEnumUnderlyingType(); + size = Marshal.SizeOf(marshalType); } catch { diff --git a/Source/Engine/Scripting/Runtime/DotNet.cpp b/Source/Engine/Scripting/Runtime/DotNet.cpp index 246c1620f..8d75d7a95 100644 --- a/Source/Engine/Scripting/Runtime/DotNet.cpp +++ b/Source/Engine/Scripting/Runtime/DotNet.cpp @@ -1163,8 +1163,8 @@ MType* MField::GetType() const int32 MField::GetOffset() const { - MISSING_CODE("TODO: MField::GetOffset"); // TODO: MField::GetOffset - return 0; + static void* FieldGetOffsetPtr = GetStaticMethodPointer(TEXT("FieldGetOffset")); + return CallStaticMethod(FieldGetOffsetPtr, _handle); } void MField::GetValue(MObject* instance, void* result) const @@ -1175,8 +1175,8 @@ void MField::GetValue(MObject* instance, void* result) const MObject* MField::GetValueBoxed(MObject* instance) const { - MISSING_CODE("TODO: MField::GetValueBoxed"); // TODO: MField::GetValueBoxed - return nullptr; + static void* FieldGetValueBoxedPtr = GetStaticMethodPointer(TEXT("FieldGetValueBoxed")); + return CallStaticMethod(FieldGetValueBoxedPtr, instance, _handle); } void MField::SetValue(MObject* instance, void* value) const