diff --git a/Source/Engine/Animations/AnimationGraph.cs b/Source/Engine/Animations/AnimationGraph.cs index 583e0383c..1fef54d99 100644 --- a/Source/Engine/Animations/AnimationGraph.cs +++ b/Source/Engine/Animations/AnimationGraph.cs @@ -269,7 +269,7 @@ namespace FlaxEngine internal static partial bool Internal_HasConnection(ref AnimationGraph.CustomNode.Context context, int boxId); [LibraryImport("FlaxEngine", EntryPoint = "AnimGraphInternal_GetInputValue")] - [return: MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))] + [return: MarshalUsing(typeof(FlaxEngine.Interop.AsManagedHandleMarshaller))] internal static partial object Internal_GetInputValue(ref AnimationGraph.CustomNode.Context context, int boxId); [LibraryImport("FlaxEngine", EntryPoint = "AnimGraphInternal_GetOutputImpulseData")] diff --git a/Source/Engine/Engine/NativeInterop.Marshallers.cs b/Source/Engine/Engine/NativeInterop.Marshallers.cs index c0048d322..18f448233 100644 --- a/Source/Engine/Engine/NativeInterop.Marshallers.cs +++ b/Source/Engine/Engine/NativeInterop.Marshallers.cs @@ -17,16 +17,16 @@ namespace FlaxEngine.Interop #if FLAX_EDITOR [HideInEditor] #endif - [CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedHandleMarshaller.ManagedToNativeState))] - [CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedOut, typeof(ManagedHandleMarshaller.ManagedToNativeState))] - [CustomMarshaller(typeof(object), MarshalMode.ElementIn, typeof(ManagedHandleMarshaller.ManagedToNative))] - [CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedOut, typeof(ManagedHandleMarshaller.NativeToManaged))] - [CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedIn, typeof(ManagedHandleMarshaller.NativeToManaged))] - [CustomMarshaller(typeof(object), MarshalMode.ElementOut, typeof(ManagedHandleMarshaller.NativeToManaged))] - [CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedRef, typeof(ManagedHandleMarshaller.Bidirectional))] - [CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedRef, typeof(ManagedHandleMarshaller.Bidirectional))] - [CustomMarshaller(typeof(object), MarshalMode.ElementRef, typeof(ManagedHandleMarshaller))] - public static class ManagedHandleMarshaller + [CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedIn, typeof(AsManagedHandleMarshaller.ManagedToNativeState))] + [CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedOut, typeof(AsManagedHandleMarshaller.ManagedToNativeState))] + [CustomMarshaller(typeof(object), MarshalMode.ElementIn, typeof(AsManagedHandleMarshaller.ManagedToNative))] + [CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedOut, typeof(AsManagedHandleMarshaller.NativeToManaged))] + [CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedIn, typeof(AsManagedHandleMarshaller.NativeToManaged))] + [CustomMarshaller(typeof(object), MarshalMode.ElementOut, typeof(AsManagedHandleMarshaller.NativeToManaged))] + [CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedRef, typeof(AsManagedHandleMarshaller.Bidirectional))] + [CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedRef, typeof(AsManagedHandleMarshaller.Bidirectional))] + [CustomMarshaller(typeof(object), MarshalMode.ElementRef, typeof(AsManagedHandleMarshaller))] + public static class AsManagedHandleMarshaller { #if FLAX_EDITOR [HideInEditor] @@ -132,7 +132,7 @@ namespace FlaxEngine.Interop public IntPtr ToUnmanaged() { - unmanaged = ManagedHandleMarshaller.ToNative(managed); + unmanaged = AsManagedHandleMarshaller.ToNative(managed); return unmanaged; } @@ -143,7 +143,7 @@ namespace FlaxEngine.Interop public object ToManaged() { - managed = ManagedHandleMarshaller.ToManaged(unmanaged); + managed = AsManagedHandleMarshaller.ToManaged(unmanaged); unmanaged = IntPtr.Zero; return managed; } @@ -177,7 +177,7 @@ namespace FlaxEngine.Interop [CustomMarshaller(typeof(Type), MarshalMode.Default, typeof(SystemTypeMarshaller))] public static class SystemTypeMarshaller { - public static Type ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As(ManagedHandleMarshaller.ConvertToManaged(unmanaged)).type : null; + public static Type ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As(AsManagedHandleMarshaller.ConvertToManaged(unmanaged)).type : null; public static IntPtr ConvertToUnmanaged(Type managed) { @@ -199,9 +199,9 @@ namespace FlaxEngine.Interop [CustomMarshaller(typeof(Exception), MarshalMode.Default, typeof(ExceptionMarshaller))] public static class ExceptionMarshaller { - public static Exception ConvertToManaged(IntPtr unmanaged) => Unsafe.As(ManagedHandleMarshaller.ConvertToManaged(unmanaged)); - public static IntPtr ConvertToUnmanaged(Exception managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed); - public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged); + public static Exception ConvertToManaged(IntPtr unmanaged) => Unsafe.As(AsManagedHandleMarshaller.ConvertToManaged(unmanaged)); + public static IntPtr ConvertToUnmanaged(Exception managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed); + public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged); } #if FLAX_EDITOR @@ -225,9 +225,9 @@ namespace FlaxEngine.Interop [CustomMarshaller(typeof(CultureInfo), MarshalMode.Default, typeof(CultureInfoMarshaller))] public static class CultureInfoMarshaller { - public static CultureInfo ConvertToManaged(IntPtr unmanaged) => Unsafe.As(ManagedHandleMarshaller.ConvertToManaged(unmanaged)); - public static IntPtr ConvertToUnmanaged(CultureInfo managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed); - public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged); + public static CultureInfo ConvertToManaged(IntPtr unmanaged) => Unsafe.As(AsManagedHandleMarshaller.ConvertToManaged(unmanaged)); + public static IntPtr ConvertToUnmanaged(CultureInfo managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed); + public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged); } #if FLAX_EDITOR @@ -236,9 +236,9 @@ namespace FlaxEngine.Interop [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); + public static Version ConvertToManaged(IntPtr unmanaged) => Unsafe.As(AsManagedHandleMarshaller.ConvertToManaged(unmanaged)); + public static IntPtr ConvertToUnmanaged(Version managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed); + public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged); } #if FLAX_EDITOR diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index c2b28f90a..629b3e4c1 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -785,7 +785,7 @@ namespace FlaxEngine.Interop for (int i = 0; i < numParams; i++) { IntPtr nativePtr = Unsafe.Read((IntPtr.Add(paramPtr, sizeof(IntPtr) * i)).ToPointer()); - methodParameters[i] = MarshalToManaged(nativePtr, methodHolder.parameterTypes[i]); + methodParameters[i] = MarshalToManaged2(nativePtr, methodHolder.parameterTypes[i]); } try diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index c4dfff571..76159ebd8 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -19,6 +19,8 @@ using System.IO; using System.Text; using System.Threading; using System.Buffers; +using System.Runtime.InteropServices.Marshalling; +using FlaxEngine.Utilities; namespace FlaxEngine.Interop { @@ -410,6 +412,164 @@ namespace FlaxEngine.Interop internal static ConcurrentDictionary toNativeMarshallers = new ConcurrentDictionary(1, 3); internal static ConcurrentDictionary toNativeFieldMarshallers = new ConcurrentDictionary(1, 3); + internal static ConcurrentDictionary)> _marshallers = new(1, 3); + + internal static object MarshalToManaged2(IntPtr nativePtr, Type type) + { + static MarshalToManagedDelegate Factory(Type type) + { + Type marshalType = type; + if (marshalType.IsByRef) + marshalType = marshalType.GetElementType(); + else if (marshalType.IsPointer) + marshalType = typeof(IntPtr); + + MethodInfo method = typeof(MarshalHelper<>).MakeGenericType(marshalType).GetMethod(nameof(MarshalHelper.ToManagedWrapper), BindingFlags.Static | BindingFlags.NonPublic); + return method.CreateDelegate(); + } + + static Type GetCustomMarshaller(Type type) + { + if (type == typeof(bool)) + return typeof(BooleanMarshaller); + else if (type.IsArray) + return null; + + Type marshallerType = type.GetCustomAttribute()?.NativeType; + //if (marshallerType == null && marshallerType != type) + // marshallerType = type.GetCustomAttribute()?.NativeType; + + return marshallerType; + } + static (Type, Func) Factory2(Type type) + { + Type marshalType = type; + if (marshalType.IsByRef) + marshalType = marshalType.GetElementType(); + else if (marshalType == typeof(byte*) || marshalType == typeof(char*)) + { + } + else if (marshalType.IsPointer) + marshalType = typeof(IntPtr); + + Type marshallerType = GetCustomMarshaller(marshalType); + if (marshalType.IsArray) + { + Type elementType = marshalType.GetElementType(); + Type elementMarshallerType = GetCustomMarshaller(elementType); + if (elementMarshallerType == null) + { + + } + else + { + MethodInfo method2 = elementMarshallerType.GetMethod("ConvertToManaged", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + var elementInternalType = method2.GetParameters()[0].ParameterType; + var types2 = new Type[] { elementType, elementInternalType }; + marshallerType = typeof(NativeArrayMarshaller<,>).MakeGenericType(types2); + } + } + if (marshallerType == null) + { + if (marshalType == typeof(IntPtr)) + { + Func func = (obj) => obj; + return (typeof(IntPtr), func); + } + else if (marshalType == typeof(ManagedHandle)) + { + Func func = (obj) => ManagedHandle.FromIntPtr((IntPtr)obj); + return (typeof(IntPtr), func); + } + } + if (marshallerType == null) + return (null, null); + + MethodInfo method = marshallerType.GetMethod("ConvertToManaged", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + if (method == null) + { + // [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.ManagedToUnmanagedOut, typeof(NativeArrayMarshaller<,>.NativeToManaged))] + // [CustomMarshaller(typeof(CustomMarshallerAttribute.GenericPlaceholder[]), MarshalMode.UnmanagedToManagedIn, typeof(NativeArrayMarshaller<,>.NativeToManaged))] + + var customMarshallerAttributes = marshallerType.GetCustomAttributes(); + foreach (var attrib in customMarshallerAttributes) + { + if (attrib.MarshalMode == MarshalMode.ManagedToUnmanagedOut) + { + var asdf = typeof(NativeArrayMarshaller<,>.NativeToManaged); + marshallerType = attrib.MarshallerType; + //method = marshallerType.GetMethod("ConvertToManaged", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + } + } + + return (null, null); + } + + var internalType = method.GetParameters()[0].ParameterType; + var types = new Type[] { marshalType, internalType }; + var convertDelegate = method.CreateDelegate(typeof(ToManagedDelegate<,>).MakeGenericType(types)); + if (internalType.IsStructure()) + { + Func func = + (obj) => convertDelegate.DynamicInvoke(obj); + return (internalType, func); + } + else + { + Func func = + (obj) => convertDelegate.DynamicInvoke(obj); + return (internalType, func); + } + } + + var type2 = type.IsByRef ? type.GetElementType() : type; + if (!_marshallers.TryGetValue(type, out var marsh)) + marsh = _marshallers.GetOrAdd(type, Factory2); + if (!toManagedMarshallers.TryGetValue(type, out var deleg)) + deleg = toManagedMarshallers.GetOrAdd(type, Factory); + + if (marsh.Item2 != null) + { + object conv1 = deleg(nativePtr, type.IsByRef && false); + if (type.IsByRef && marsh.Item1 == typeof(IntPtr)) + nativePtr = Unsafe.Read(nativePtr.ToPointer()); + object value = marsh.Item1 == typeof(IntPtr) ? nativePtr : Marshal.PtrToStructure(nativePtr, marsh.Item1);//Unsafe.Read(nativePtr.ToPointer()); + object conv2 = marsh.Item2(value); + if (conv1 is null && conv2 is null) + { } + else if (!conv1.Equals(conv2)) + Assert.IsTrue(conv1.Equals(conv2)); + return conv2; + } + else if (type2 == typeof(bool)) + { + //object conv1 = deleg(nativePtr, type.IsByRef && false); + byte value = Unsafe.Read(nativePtr.ToPointer()); + object conv2 = BooleanMarshaller.ConvertToManaged(value); + //Assert.IsTrue(conv1.Equals(conv2)); + return conv2; + } + else if (type2 == typeof(ManagedHandle)) + { + //ManagedHandle conv1 = (ManagedHandle)deleg(nativePtr, type.IsByRef && false); + ManagedHandle conv2 = ManagedHandle.FromIntPtr(nativePtr); + //Assert.IsTrue(conv1.Equals(conv2)); + return conv2; + } + else if (type2 == typeof(int) || type2.IsEnum || + type2 == typeof(IntPtr) || type2 == typeof(Float2) || type2 == typeof(Float3) || type2 == typeof(Guid)) + { + + } + else + { + + } + + + return deleg(nativePtr, type.IsByRef && false); + } + internal static object MarshalToManaged(IntPtr nativePtr, Type type) { static MarshalToManagedDelegate Factory(Type type) @@ -583,9 +743,6 @@ namespace FlaxEngine.Interop MethodInfo toManagedFieldMethod; MethodInfo toNativeFieldMethod; - if (fieldType == typeof(string)) - fieldType = fieldType; - if (fieldType == typeof(SoftTypeReference)) { if (type.IsValueType) @@ -1409,12 +1566,6 @@ namespace FlaxEngine.Interop var offsets = MarshalHelper.marshallableFieldOffsets; var marshallers = MarshalHelper.toNativeFieldMarshallers; - for (int i = 1; i < offsets.Length; i++) - { - if (offsets[i - 1] > offsets[i]) - fieldPtr = fieldPtr; - } - for (int i = 0; i < fields.Length; i++) { marshallers[i](fields[i], offsets[i], ref managedValue, nativePtr, out int fieldSize); diff --git a/Source/Engine/Scripting/Internal/EngineInternalCalls.cpp b/Source/Engine/Scripting/Internal/EngineInternalCalls.cpp index 2a56b3abd..a3c5cc2dd 100644 --- a/Source/Engine/Scripting/Internal/EngineInternalCalls.cpp +++ b/Source/Engine/Scripting/Internal/EngineInternalCalls.cpp @@ -37,7 +37,7 @@ DEFINE_INTERNAL_CALL(MObject*) UtilsInternal_ExtractArrayFromList(MObject* obj) //#if USE_NETCORE //APgI_TYPEDEF() typedef MString* ManagedString; -API_TYPEDEF() typedef String* ManagedString; +API_TYPEDEF() typedef const String& ManagedString; //#endif DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size) @@ -58,11 +58,14 @@ DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, con DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, ManagedString msgObj) { #if LOG_ENABLE + +#if USE_NETCORE + if (msgObj.IsEmpty()) + return; + StringView msg(msgObj); +#else if (msgObj == nullptr) return; -#if USE_NETCORE - StringView msg(*msgObj); -#else StringView msg; MUtils::ToString(msgObj, msg); #endif @@ -73,11 +76,15 @@ DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, Manag DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, ManagedString msgObj, ScriptingObject* obj, ManagedString stackTrace) { #if LOG_ENABLE + +#if USE_NETCORE + if (msgObj.IsEmpty()) + return; + StringView msg(msgObj); +#else if (msgObj == nullptr) return; -#if USE_NETCORE - StringView msg(*msgObj); -#else + // Get info StringView msg; MUtils::ToString(msgObj, msg); @@ -135,11 +142,13 @@ namespace DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(ManagedString nameObj) { #if COMPILE_WITH_PROFILER +#if USE_NETCORE + if (nameObj.IsEmpty()) + return; + StringView name(nameObj); +#else if (nameObj == nullptr) return; -#if USE_NETCORE - StringView name(*nameObj); -#else StringView name; MUtils::ToString(nameObj, name); #endif @@ -198,10 +207,12 @@ DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(ManagedString nameObj) { #if COMPILE_WITH_PROFILER #if USE_NETCORE + if (nameObj.IsEmpty()) + return; + const StringView nameChars(nameObj); +#else if (nameObj == nullptr) return; - const StringView nameChars(*nameObj); -#else const StringView nameChars = MCore::String::GetChars(nameObj); #endif const auto index = ProfilerGPU::BeginEvent(nameChars.Get()); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 84eb90d20..4dce89444 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -625,7 +625,7 @@ namespace Flax.Build.Bindings else if (returnValueType == "Version") returnMarshalType = "MarshalUsing(typeof(VersionMarshaller))"; else if (functionInfo.ReturnType.Type == "Variant") // object - returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))"; + returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.AsManagedHandleMarshaller))"; else if (FindApiTypeInfo(buildData, functionInfo.ReturnType, caller)?.IsInterface ?? false) { var apiType = FindApiTypeInfo(buildData, functionInfo.ReturnType, caller); @@ -786,7 +786,7 @@ namespace Flax.Build.Bindings 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))"; + parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.AsManagedHandleMarshaller))"; else if (parameterInfo.Type.Type == "MonoArray" || parameterInfo.Type.Type == "MArray") parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))"; else if (nativeType == "object[]") @@ -1756,7 +1756,7 @@ namespace Flax.Build.Bindings #endif public static class NativeToManaged { - public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged)); + public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged)); public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => managed != null ? ManagedHandle.ToIntPtr(managed, GCHandleType.Weak) : IntPtr.Zero; public static void Free(IntPtr unmanaged) {} } @@ -1765,28 +1765,28 @@ namespace Flax.Build.Bindings #endif public static class ManagedToNative { - public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged)); + public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged)); public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => managed != null ? ManagedHandle.ToIntPtr(managed/*, GCHandleType.Weak*/) : IntPtr.Zero; - public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged); + public static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged); } #if FLAX_EDITOR [HideInEditor] #endif public struct Bidirectional { - ManagedHandleMarshaller.Bidirectional marsh; + AsManagedHandleMarshaller.Bidirectional marsh; public void FromManaged({{classInfo.Name}} managed) => marsh.FromManaged(managed); public IntPtr ToUnmanaged() => marsh.ToUnmanaged(); public void FromUnmanaged(IntPtr unmanaged) => marsh.FromUnmanaged(unmanaged); public {{classInfo.Name}} ToManaged() => Unsafe.As<{{classInfo.Name}}>(marsh.ToManaged()); public void Free() => marsh.Free(); } - internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.ConvertToManaged(unmanaged)); - internal static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => ManagedHandleMarshaller.ConvertToUnmanaged(managed); - internal static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.Free(unmanaged); + internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.ConvertToManaged(unmanaged)); + internal static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed); + internal static void Free(IntPtr unmanaged) => AsManagedHandleMarshaller.Free(unmanaged); - internal static {{classInfo.Name}} ToManaged(IntPtr managed) => Unsafe.As<{{classInfo.Name}}>(ManagedHandleMarshaller.ToManaged(managed)); - internal static IntPtr ToNative({{classInfo.Name}} managed) => ManagedHandleMarshaller.ToNative(managed); + internal static {{classInfo.Name}} ToManaged(IntPtr managed) => Unsafe.As<{{classInfo.Name}}>(AsManagedHandleMarshaller.ToManaged(managed)); + internal static IntPtr ToNative({{classInfo.Name}} managed) => AsManagedHandleMarshaller.ToNative(managed); #pragma warning restore 618 #pragma warning restore 1591 } @@ -2051,8 +2051,8 @@ namespace Flax.Build.Bindings else if (marshalType.Type == "Variant") { // Variant passed as boxed object handle - toManagedContent.AppendLine($"ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged.{fieldInfo.Name});"); - toNativeContent.AppendLine($"ManagedHandleMarshaller.NativeToManaged.ConvertToUnmanaged(managed.{fieldInfo.Name});"); + toManagedContent.AppendLine($"AsManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged.{fieldInfo.Name});"); + toNativeContent.AppendLine($"AsManagedHandleMarshaller.NativeToManaged.ConvertToUnmanaged(managed.{fieldInfo.Name});"); } else if (internalType) { @@ -2537,8 +2537,8 @@ namespace Flax.Build.Bindings contents.Append(indent).AppendLine("{"); contents.AppendLine("#pragma warning disable 1591"); contents.AppendLine("#pragma warning disable 618"); - 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 {interfaceInfo.Name} ConvertToManaged(IntPtr unmanaged) => ({interfaceInfo.Name})AsManagedHandleMarshaller.ConvertToManaged(unmanaged);"); + contents.Append(indent).Append(" ").AppendLine($"internal static IntPtr ConvertToUnmanaged({interfaceInfo.Name} managed) => AsManagedHandleMarshaller.ConvertToUnmanaged(managed);"); contents.AppendLine("#pragma warning restore 618"); contents.AppendLine("#pragma warning restore 1591"); contents.Append(indent).AppendLine("}"); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 004d89005..f571c7d2c 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -176,19 +176,26 @@ namespace Flax.Build.Bindings if (paramType.IsPtr) result = string.Format(nativeToManaged, '*' + paramName); var origType = paramType.ToString(); - contents.Append($" // localvar1 {managedTypeAsNative}, {origType}, isRef: {isRef}, typeIsRef: {paramType.IsRef}").AppendLine(); + var origType2 = paramType.Type; + contents.Append($" // localvar1 {managedTypeAsNative}, {origType}, {origType2}, isRef: {isRef}, typeIsRef: {paramType.IsRef}").AppendLine(); if (isRef) { - if (origType == managedTypeAsNative) - contents.Append($" auto& __param_orig_{paramName} = {result};").AppendLine(); + if (origType2 == managedTypeAsNative) + { + //contents.Append($" auto& __param_orig_{paramName} = {result};").AppendLine(); + contents.Append($" auto& __param_{paramName} = {result};").AppendLine(); + } else + { contents.Append($" auto __param_orig_{paramName} = {result};").AppendLine(); - contents.Append($" auto __param_{paramName} = __param_orig_{paramName};").AppendLine(); + contents.Append($" auto __param_{paramName} = __param_orig_{paramName};").AppendLine(); + } + //contents.Append($" auto __param_{paramName} = __param_orig_{paramName};").AppendLine(); } else { - if (origType == managedTypeAsNative) + if (origType2 == managedTypeAsNative) contents.Append($" auto& __param_{paramName} = {result};").AppendLine(); else contents.Append($" auto __param_{paramName} = {result};").AppendLine(); diff --git a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs index 13ecd1982..c7987c018 100644 --- a/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs +++ b/Source/Tools/Flax.Build/Build/NativeCpp/BuildOptions.cs @@ -375,6 +375,7 @@ namespace Flax.Build.NativeCpp "System.Reflection", //"System.Reflection.Metadata", + "System.Numerics.Vectors", }, SystemAnalyzers = new HashSet {