From 8e2f3ec0c0dee02a83c78c80bf246ddf34de4f10 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 6 Mar 2025 00:36:39 +0100 Subject: [PATCH] Fix `Version` marshaling as parameter --- .../Engine/NativeInterop.Marshallers.cs | 11 +++ .../Engine/Engine/NativeInterop.Unmanaged.cs | 86 ------------------- Source/Engine/Scripting/Scripting.cs | 17 ++-- .../Bindings/BindingsGenerator.CSharp.cs | 9 ++ 4 files changed, 27 insertions(+), 96 deletions(-) diff --git a/Source/Engine/Engine/NativeInterop.Marshallers.cs b/Source/Engine/Engine/NativeInterop.Marshallers.cs index 82359e1b4..63c0f7bc8 100644 --- a/Source/Engine/Engine/NativeInterop.Marshallers.cs +++ b/Source/Engine/Engine/NativeInterop.Marshallers.cs @@ -225,6 +225,17 @@ namespace FlaxEngine.Interop public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged); } +#if FLAX_EDITOR + [HideInEditor] +#endif + [CustomMarshaller(typeof(Version), MarshalMode.Default, typeof(VersionMarshaller))] + public static class VersionMarshaller + { + public static Version ConvertToManaged(IntPtr unmanaged) => Unsafe.As(ManagedHandleMarshaller.ConvertToManaged(unmanaged)); + public static IntPtr ConvertToUnmanaged(Version managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed); + public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged); + } + #if FLAX_EDITOR [HideInEditor] #endif diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index e0900f663..6c6858a20 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -56,90 +56,6 @@ namespace FlaxEngine.Interop internal uint setterAttributes; } - [StructLayout(LayoutKind.Explicit)] - public struct NativeVariant - { - [StructLayout(LayoutKind.Sequential)] - internal struct NativeVariantType - { - internal VariantUtils.VariantType types; - internal IntPtr TypeName; // char* - } - - [FieldOffset(0)] - NativeVariantType Type; - - [FieldOffset(8)] - byte AsBool; - - [FieldOffset(8)] - short AsInt16; - - [FieldOffset(8)] - ushort AsUint16; - - [FieldOffset(8)] - int AsInt; - - [FieldOffset(8)] - uint AsUint; - - [FieldOffset(8)] - long AsInt64; - - [FieldOffset(8)] - ulong AsUint64; - - [FieldOffset(8)] - float AsFloat; - - [FieldOffset(8)] - double AsDouble; - - [FieldOffset(8)] - IntPtr AsPointer; - - [FieldOffset(8)] - int AsData0; - - [FieldOffset(12)] - int AsData1; - - [FieldOffset(16)] - int AsData2; - - [FieldOffset(20)] - int AsData3; - - [FieldOffset(24)] - int AsData4; - - [FieldOffset(28)] - int AsData5; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct NativeVersion - { - internal int _Major; - internal int _Minor; - internal int _Build; - internal int _Revision; - - internal NativeVersion(Version ver) - { - _Major = ver.Major; - _Minor = ver.Minor; - _Build = ver.Build; - _Revision = ver.Revision; - } - - internal Version GetVersion() - { - return new Version(_Major, _Minor, _Build, _Revision); - } - } - unsafe partial class NativeInterop { [LibraryImport("FlaxEngine", EntryPoint = "NativeInterop_CreateClass", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))] @@ -1100,8 +1016,6 @@ namespace FlaxEngine.Interop { Type type = Unsafe.As(typeHandle.Target); Type nativeType = GetInternalType(type) ?? type; - if (nativeType == typeof(Version)) - nativeType = typeof(NativeVersion); int size; if (nativeType.IsClass) size = sizeof(IntPtr); diff --git a/Source/Engine/Scripting/Scripting.cs b/Source/Engine/Scripting/Scripting.cs index 8faf52c2b..39fdba696 100644 --- a/Source/Engine/Scripting/Scripting.cs +++ b/Source/Engine/Scripting/Scripting.cs @@ -232,7 +232,13 @@ namespace FlaxEngine internal static ManagedHandle VersionToManaged(int major, int minor, int build, int revision) { - Version version = new Version(major, minor, Math.Max(build, 0), Math.Max(revision, 0)); + Version version; + if (revision >= 0) + version = new Version(major, minor, Math.Max(build, 0), revision); + else if (build >= 0) + version = new Version(major, minor, build); + else + version = new Version(major, minor); return ManagedHandle.Alloc(version); } @@ -245,15 +251,6 @@ namespace FlaxEngine return ManagedHandle.Alloc(new CultureInfo(lcid)); } - [StructLayout(LayoutKind.Sequential)] - internal struct VersionNative - { - public int Major; - public int Minor; - public int Build; - public int Revision; - } - internal static void VersionToNative(ManagedHandle versionHandle, ref int major, ref int minor, ref int build, ref int revision) { Version version = Unsafe.As(versionHandle.Target); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index b524e1648..72f052afa 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -615,6 +615,8 @@ namespace Flax.Build.Bindings returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemTypeMarshaller))"; else if (returnValueType == "CultureInfo") returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.CultureInfoMarshaller))"; + else if (returnValueType == "Version") + returnMarshalType = "MarshalUsing(typeof(VersionMarshaller))"; else if (functionInfo.ReturnType.Type == "Variant") // object returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))"; else if (FindApiTypeInfo(buildData, functionInfo.ReturnType, caller)?.IsInterface ?? false) @@ -676,6 +678,8 @@ namespace Flax.Build.Bindings parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemTypeMarshaller))"; else if (parameterInfo.Type.Type == "CultureInfo") parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.CultureInfoMarshaller))"; + else if (parameterInfo.Type.Type == "Version") + parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.VersionMarshaller))"; else if (parameterInfo.Type.Type == "Variant") // object parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))"; else if (parameterInfo.Type.Type == "MonoArray" || parameterInfo.Type.Type == "MArray") @@ -731,10 +735,15 @@ namespace Flax.Build.Bindings string parameterMarshalType = ""; if (parameterInfo.IsOut && parameterInfo.DefaultValue == "var __resultAsRef") { + // TODO: make this code shared with MarshalUsing selection from the above if (parameterInfo.Type.Type == "Array" || parameterInfo.Type.Type == "Span" || parameterInfo.Type.Type == "DataContainer" || parameterInfo.Type.Type == "BytesContainer") parameterMarshalType = $"MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = \"{parameterInfo.Name}Count\")"; else if (parameterInfo.Type.Type == "Dictionary") parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.DictionaryMarshaller<,>), ConstantElementCount = 0)"; + else if (parameterInfo.Type.Type == "CultureInfo") + parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.CultureInfoMarshaller))"; + else if (parameterInfo.Type.Type == "Version") + parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.VersionMarshaller))"; } if (nativeType == "System.Type") parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemTypeMarshaller))";