From 1a1fadcc2fe0d44754c55e7fb4264a6c5cd5b5cd Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sat, 14 Jan 2023 17:50:25 +0200 Subject: [PATCH 1/4] Fix incorrect marshalling of TextureImportEntry fields --- Source/Editor/Content/Import/TextureImportEntry.cs | 4 ++-- Source/Engine/Engine/NativeInterop.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Content/Import/TextureImportEntry.cs b/Source/Editor/Content/Import/TextureImportEntry.cs index 157d82249..f03ef86ac 100644 --- a/Source/Editor/Content/Import/TextureImportEntry.cs +++ b/Source/Editor/Content/Import/TextureImportEntry.cs @@ -368,8 +368,8 @@ namespace FlaxEditor.Content.Import MaxSize = managed.MaxSize, TextureGroup = managed.TextureGroup, Size = managed.Size, - SpriteAreas = managed.SpriteAreas != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray((ManagedArray)GCHandle.FromIntPtr(managed.SpriteAreas).Target) : null, - SpriteNames = managed.SpriteNames != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray((ManagedArray)GCHandle.FromIntPtr(managed.SpriteNames).Target) : null, + SpriteAreas = managed.SpriteAreas != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.SpriteAreas).Target).GetArray() : null, + SpriteNames = managed.SpriteNames != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray((ManagedArray)ManagedHandle.FromIntPtr(managed.SpriteNames).Target) : null, }; } internal static InternalOptionsNative ToNative(InternalOptions managed) diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 9ee57e3cd..7afa25b79 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -1114,7 +1114,7 @@ namespace FlaxEngine NativeMemory.AlignedFree(ptr); } - internal static T[] GCHandleArrayToManagedArray(ManagedArray ptrArray) + internal static T[] GCHandleArrayToManagedArray(ManagedArray ptrArray) where T : class { Span span = ptrArray.GetSpan(); T[] managedArray = new T[ptrArray.Length]; From be720257cabbeb3d1137a76ff8ef383dfcfa7a50 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Mon, 16 Jan 2023 20:11:14 +0200 Subject: [PATCH 2/4] Fix crash when marshalling generated managed interfaces Marshaller returns a permanent handle, avoid releasing it during marshalling --- Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 341fd6746..80472ebbc 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -1932,7 +1932,6 @@ namespace Flax.Build.Bindings contents.AppendLine("#pragma warning disable 1591"); contents.Append(indent).Append(" ").AppendLine($"internal static {interfaceInfo.Name} ConvertToManaged(IntPtr unmanaged) => ({interfaceInfo.Name})ManagedHandleMarshaller.ConvertToManaged(unmanaged);"); contents.Append(indent).Append(" ").AppendLine($"internal static IntPtr ConvertToUnmanaged({interfaceInfo.Name} managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed);"); - contents.Append(indent).Append(" ").AppendLine("internal static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged);"); contents.AppendLine("#pragma warning restore 1591"); contents.Append(indent).AppendLine("}"); } From a917567e924de84bd4d9eb98b7e440990130c892 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 22 Jan 2023 17:28:44 +0200 Subject: [PATCH 3/4] Fix passing weak managed string handles in marshallers --- Source/Engine/Engine/NativeInterop.cs | 21 ++++++++++++++----- Source/Engine/Engine/NativeInterop_Invoker.cs | 8 +++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index 7afa25b79..8317c72ce 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -331,6 +331,17 @@ namespace FlaxEngine [System.Diagnostics.DebuggerStepThrough] internal static unsafe IntPtr ToNative(string str) + { + if (str == null) + return IntPtr.Zero; + else if (str == string.Empty) + return ManagedHandle.ToIntPtr(EmptyStringHandle); + Assert.IsTrue(str.Length > 0); + return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(str)); + } + + [System.Diagnostics.DebuggerStepThrough] + internal static unsafe IntPtr ToNativeWeak(string str) { if (str == null) return IntPtr.Zero; @@ -969,7 +980,7 @@ namespace FlaxEngine { if (managed == null) return IntPtr.Zero; - return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed, GCHandleType.Weak)); + return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed)); } public static void Free(IntPtr unmanaged) => ManagedString.Free(unmanaged); @@ -1718,7 +1729,7 @@ namespace FlaxEngine IntPtr managedPtr; if (type == typeof(string)) - managedPtr = ManagedString.ToNative(managedValue as string); + managedPtr = ManagedString.ToNativeWeak(managedValue as string); else if (type.IsPointer) { if (Pointer.Unbox(managedValue) == null) @@ -2242,19 +2253,19 @@ namespace FlaxEngine [UnmanagedCallersOnly] internal static IntPtr NewStringUTF16(char* text, int length) { - return ManagedString.ToNative(new string(new ReadOnlySpan(text, length))); + return ManagedString.ToNativeWeak(new string(new ReadOnlySpan(text, length))); } [UnmanagedCallersOnly] internal static IntPtr NewString(sbyte* text) { - return ManagedString.ToNative(new string(text)); + return ManagedString.ToNativeWeak(new string(text)); } [UnmanagedCallersOnly] internal static IntPtr NewStringLength(sbyte* text, int length) { - return ManagedString.ToNative(new string(text, 0, length)); + return ManagedString.ToNativeWeak(new string(text, 0, length)); } /// diff --git a/Source/Engine/Engine/NativeInterop_Invoker.cs b/Source/Engine/Engine/NativeInterop_Invoker.cs index 39d080ff1..56b225767 100644 --- a/Source/Engine/Engine/NativeInterop_Invoker.cs +++ b/Source/Engine/Engine/NativeInterop_Invoker.cs @@ -78,7 +78,7 @@ namespace FlaxEngine if (returnValue == null) return IntPtr.Zero; if (typeof(TRet) == typeof(string)) - return ManagedString.ToNative(Unsafe.As(returnValue)); + return ManagedString.ToNativeWeak(Unsafe.As(returnValue)); if (typeof(TRet) == typeof(IntPtr)) return (IntPtr)(object)returnValue; if (typeof(TRet) == typeof(ManagedHandle)) @@ -102,7 +102,7 @@ namespace FlaxEngine if (returnObject == null) return IntPtr.Zero; if (returnType == typeof(string)) - return ManagedString.ToNative(Unsafe.As(returnObject)); + return ManagedString.ToNativeWeak(Unsafe.As(returnObject)); if (returnType == typeof(IntPtr)) return (IntPtr)returnObject; if (returnType == typeof(ManagedHandle)) @@ -123,7 +123,7 @@ namespace FlaxEngine if (returnValue == null) return IntPtr.Zero; if (typeof(TRet) == typeof(string)) - return ManagedString.ToNative(Unsafe.As(returnValue)); + return ManagedString.ToNativeWeak(Unsafe.As(returnValue)); if (typeof(TRet) == typeof(IntPtr)) return (IntPtr)(object)returnValue; if (typeof(TRet) == typeof(ManagedHandle)) @@ -160,7 +160,7 @@ namespace FlaxEngine if (returnObject == null) return IntPtr.Zero; if (returnType == typeof(string)) - return ManagedString.ToNative(Unsafe.As(returnObject)); + return ManagedString.ToNativeWeak(Unsafe.As(returnObject)); if (returnType == typeof(IntPtr)) return (IntPtr)(object)returnObject; if (returnType == typeof(ManagedHandle)) From 3ca0ea2e507dcfe561cfb20d7609bab067fb470f Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Sun, 22 Jan 2023 17:22:24 +0200 Subject: [PATCH 4/4] Fix unfreed managed string handles --- Source/Editor/Content/Import/ModelImportEntry.cs | 2 ++ Source/Editor/Editor.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Source/Editor/Content/Import/ModelImportEntry.cs b/Source/Editor/Content/Import/ModelImportEntry.cs index cf4672154..d0a680f3a 100644 --- a/Source/Editor/Content/Import/ModelImportEntry.cs +++ b/Source/Editor/Content/Import/ModelImportEntry.cs @@ -566,6 +566,8 @@ namespace FlaxEditor.Content.Import } internal static void Free(InternalOptionsNative unmanaged) { + ManagedString.Free(unmanaged.CollisionMeshesPrefix); + ManagedString.Free(unmanaged.RootNodeName); } } diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index dcf41a072..2e38b7d90 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -1259,6 +1259,8 @@ namespace FlaxEditor } internal static void Free(VisualScriptLocalNative unmanaged) { + ManagedString.Free(unmanaged.Value); + ManagedString.Free(unmanaged.ValueTypeName); } }