From ceacdc8d08ecc4d8b0aad22f9f6318c5192c763d Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Tue, 3 Jan 2023 14:34:16 +0100 Subject: [PATCH] Fixes for dotnet7 bindings to pass unit tests --- Source/Engine/Engine/NativeInterop.cs | 92 ++++++-- Source/Engine/Engine/NativeInterop_Invoker.cs | 213 ++++++++---------- .../Bindings/BindingsGenerator.Cpp.cs | 10 +- 3 files changed, 169 insertions(+), 146 deletions(-) diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index a02601ee0..e9041f55f 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -1255,9 +1255,9 @@ namespace FlaxEngine return method.CreateDelegate(); } - if (toManagedMarshallers.TryGetValue(type, out var deleg)) - return deleg(nativePtr, type.IsByRef); - return toManagedMarshallers.GetOrAdd(type, Factory)(nativePtr, type.IsByRef); + if (!toManagedMarshallers.TryGetValue(type, out var deleg)) + deleg = toManagedMarshallers.GetOrAdd(type, Factory); + return deleg(nativePtr, type.IsByRef); } internal static void MarshalToNative(object managedObject, IntPtr nativePtr, Type type) @@ -1272,10 +1272,9 @@ namespace FlaxEngine return method.CreateDelegate(); } - if (toNativeMarshallers.TryGetValue(type, out var deleg)) - deleg(managedObject, nativePtr); - else - toNativeMarshallers.GetOrAdd(type, Factory)(managedObject, nativePtr); + if (!toNativeMarshallers.TryGetValue(type, out var deleg)) + deleg = toNativeMarshallers.GetOrAdd(type, Factory); + deleg(managedObject, nativePtr); } internal static MarshalToNativeFieldDelegate GetToNativeFieldMarshallerDelegate(Type type) @@ -1406,6 +1405,20 @@ namespace FlaxEngine toManagedTypedMarshaller(ref managedValue, nativePtr, byRef); } + internal static T ToManagedUnbox(IntPtr nativePtr) + { + T managed = default; + if (nativePtr != IntPtr.Zero) + { + Type type = typeof(T); + if (type.IsArray) + managed = (T)MarshalToManaged(nativePtr, type); // Array might be in internal format of custom structs so unbox if need to + else + managed = (T)ManagedHandle.FromIntPtr(nativePtr).Target; + } + return managed; + } + internal static Array ToManagedArray(Span ptrSpan) { T[] arr = new T[ptrSpan.Length]; @@ -1414,6 +1427,18 @@ namespace FlaxEngine return arr; } + internal static Array ToManagedArray(ManagedArray nativeArray) + { + T[] arr = new T[nativeArray.Length]; + IntPtr nativePtr = nativeArray.GetPointer; + for (int i = 0; i < arr.Length; i++) + { + toManagedTypedMarshaller(ref arr[i], nativePtr, false); + nativePtr += nativeArray.ElementSize; + } + return arr; + } + internal static void ToNative(ref T managedValue, IntPtr nativePtr) { toNativeTypedMarshaller(ref managedValue, nativePtr); @@ -1604,7 +1629,8 @@ namespace FlaxEngine internal static void ToManagedArray(ref T[] managedValue, IntPtr nativePtr, bool byRef) { - Assert.IsTrue(!byRef); + if (byRef) + nativePtr = Marshal.ReadIntPtr(nativePtr); Type elementType = typeof(T); if (nativePtr != IntPtr.Zero) @@ -1612,6 +1638,8 @@ namespace FlaxEngine ManagedArray managedArray = Unsafe.As(ManagedHandle.FromIntPtr(nativePtr).Target); if (ArrayFactory.GetMarshalledType(elementType) == elementType) managedValue = Unsafe.As(managedArray.GetArray()); + else if (elementType.IsValueType) + managedValue = Unsafe.As(MarshalHelper.ToManagedArray(managedArray)); else managedValue = Unsafe.As(MarshalHelper.ToManagedArray(managedArray.GetSpan())); } @@ -1671,9 +1699,9 @@ namespace FlaxEngine internal static void ToManagedArray(ref T[] managedValue, IntPtr nativePtr, bool byRef) { - Assert.IsTrue(!byRef); + if (byRef) + nativePtr = Marshal.ReadIntPtr(nativePtr); - Type elementType = typeof(T); if (nativePtr != IntPtr.Zero) { ManagedArray managedArray = Unsafe.As(ManagedHandle.FromIntPtr(nativePtr).Target); @@ -1708,10 +1736,25 @@ namespace FlaxEngine else { var elementType = type.GetElementType(); - if (ArrayFactory.GetMarshalledType(elementType) == elementType) - managedPtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As(managedValue)), GCHandleType.Weak)); + var arr = Unsafe.As(managedValue); + var marshalledType = ArrayFactory.GetMarshalledType(elementType); + ManagedArray managedArray; + if (marshalledType == elementType) + managedArray = ManagedArray.WrapNewArray(arr); + else if (elementType.IsValueType) + { + // Convert array of custom structures into internal native layout + managedArray = ManagedArray.AllocateNewArray(arr.Length, Marshal.SizeOf(marshalledType)); + IntPtr managedArrayPtr = managedArray.GetPointer; + for (int i = 0; i < arr.Length; i++) + { + MarshalToNative(arr.GetValue(i), managedArrayPtr, elementType); + managedArrayPtr += managedArray.ElementSize; + } + } else - managedPtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(managedValue))), GCHandleType.Weak)); + managedArray = ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(arr)); + managedPtr = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedArray, GCHandleType.Weak)); } } else @@ -1756,10 +1799,15 @@ namespace FlaxEngine genericParamTypes.Add(type); } - string typeName = $"FlaxEngine.NativeInterop+Invoker+Invoker{(method.IsStatic ? "Static" : "")}{(method.ReturnType != typeof(void) ? "Ret" : "NoRet")}{parameterTypes.Length}{(genericParamTypes.Count > 0 ? "`" + genericParamTypes.Count : "")}"; - Type invokerType = genericParamTypes.Count == 0 ? Type.GetType(typeName) : Type.GetType(typeName).MakeGenericType(genericParamTypes.ToArray()); - invokeDelegate = invokerType.GetMethod(nameof(Invoker.InvokerStaticNoRet0.MarshalAndInvoke), BindingFlags.Static | BindingFlags.NonPublic).CreateDelegate(); - delegInvoke = invokerType.GetMethod(nameof(Invoker.InvokerStaticNoRet0.CreateDelegate), BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); + string invokerTypeName = $"FlaxEngine.NativeInterop+Invoker+Invoker{(method.IsStatic ? "Static" : "")}{(method.ReturnType != typeof(void) ? "Ret" : "NoRet")}{parameterTypes.Length}{(genericParamTypes.Count > 0 ? "`" + genericParamTypes.Count : "")}"; + Type invokerType = Type.GetType(invokerTypeName); + if (invokerType != null) + { + if (genericParamTypes.Count != 0) + invokerType = invokerType.MakeGenericType(genericParamTypes.ToArray()); + invokeDelegate = invokerType.GetMethod(nameof(Invoker.InvokerStaticNoRet0.MarshalAndInvoke), BindingFlags.Static | BindingFlags.NonPublic).CreateDelegate(); + delegInvoke = invokerType.GetMethod(nameof(Invoker.InvokerStaticNoRet0.CreateDelegate), BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { method }); + } } outDeleg = invokeDelegate; @@ -2267,13 +2315,12 @@ namespace FlaxEngine // Slow path, method parameters needs to be stored in heap object returnObject; int numParams = methodHolder.parameterTypes.Length; - IntPtr* nativePtrs = stackalloc IntPtr[numParams]; object[] methodParameters = new object[numParams]; for (int i = 0; i < numParams; i++) { - nativePtrs[i] = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i)); - methodParameters[i] = MarshalToManaged(nativePtrs[i], methodHolder.parameterTypes[i]); + IntPtr nativePtr = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i)); + methodParameters[i] = MarshalToManaged(nativePtr, methodHolder.parameterTypes[i]); } try @@ -2299,7 +2346,10 @@ namespace FlaxEngine { Type parameterType = methodHolder.parameterTypes[i]; if (parameterType.IsByRef) - MarshalToNative(methodParameters[i], nativePtrs[i], parameterType.GetElementType()); + { + IntPtr nativePtr = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i)); + MarshalToNative(methodParameters[i], nativePtr, parameterType.GetElementType()); + } } if (returnObject is not null) diff --git a/Source/Engine/Engine/NativeInterop_Invoker.cs b/Source/Engine/Engine/NativeInterop_Invoker.cs index bfa09bfb4..c504661d3 100644 --- a/Source/Engine/Engine/NativeInterop_Invoker.cs +++ b/Source/Engine/Engine/NativeInterop_Invoker.cs @@ -95,6 +95,19 @@ namespace FlaxEngine else return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As(returnValue))), GCHandleType.Weak)); } + // Match Mono bindings and pass value as pointer to prevent boxing it + else if (typeof(TRet) == typeof(System.Int16)) + return new IntPtr((int)(System.Int16)(object)returnValue); + else if (typeof(TRet) == typeof(System.Int32)) + return new IntPtr((int)(System.Int32)(object)returnValue); + else if (typeof(TRet) == typeof(System.Int64)) + return new IntPtr((long)(System.Int64)(object)returnValue); + else if (typeof(TRet) == typeof(System.UInt16)) + return (IntPtr)new UIntPtr((ulong)(System.UInt16)(object)returnValue); + else if (typeof(TRet) == typeof(System.UInt32)) + return (IntPtr)new UIntPtr((ulong)(System.UInt32)(object)returnValue); + else if (typeof(TRet) == typeof(System.UInt64)) + return (IntPtr)new UIntPtr((ulong)(System.UInt64)(object)returnValue); else return returnValue != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(returnValue, GCHandleType.Weak)) : IntPtr.Zero; } @@ -163,8 +176,7 @@ namespace FlaxEngine deleg(instancePtr.Target, ref param1); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); return IntPtr.Zero; } @@ -174,7 +186,7 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); deleg(instancePtr.Target, param1); @@ -213,10 +225,8 @@ namespace FlaxEngine deleg(instancePtr.Target, ref param1, ref param2); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); return IntPtr.Zero; } @@ -226,8 +236,8 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); deleg(instancePtr.Target, param1, param2); @@ -269,12 +279,9 @@ namespace FlaxEngine deleg(instancePtr.Target, ref param1, ref param2, ref param3); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); return IntPtr.Zero; } @@ -284,9 +291,9 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); deleg(instancePtr.Target, param1, param2, param3); @@ -331,14 +338,10 @@ namespace FlaxEngine deleg(instancePtr.Target, ref param1, ref param2, ref param3, ref param4); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); - if (types[3].IsByRef) - MarshalHelper.ToNative(ref param4, param4Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[3].IsByRef) MarshalHelper.ToNative(ref param4, param4Ptr); return IntPtr.Zero; } @@ -348,10 +351,10 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); - T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)ManagedHandle.FromIntPtr(paramPtrs[3]).Target : default(T4); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); + T4 param4 = MarshalHelper.ToManagedUnbox(paramPtrs[3]); deleg(instancePtr.Target, param1, param2, param3, param4); @@ -423,8 +426,7 @@ namespace FlaxEngine deleg(ref param1); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); return IntPtr.Zero; } @@ -434,7 +436,7 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); deleg(param1); @@ -473,10 +475,8 @@ namespace FlaxEngine deleg(ref param1, ref param2); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); return IntPtr.Zero; } @@ -486,8 +486,8 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); deleg(param1, param2); @@ -529,12 +529,9 @@ namespace FlaxEngine deleg(ref param1, ref param2, ref param3); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); return IntPtr.Zero; } @@ -544,9 +541,9 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); deleg(param1, param2, param3); @@ -591,14 +588,10 @@ namespace FlaxEngine deleg(ref param1, ref param2, ref param3, ref param4); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); - if (types[3].IsByRef) - MarshalHelper.ToNative(ref param4, param4Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[3].IsByRef) MarshalHelper.ToNative(ref param4, param4Ptr); return IntPtr.Zero; } @@ -608,10 +601,10 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); - T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)ManagedHandle.FromIntPtr(paramPtrs[3]).Target : default(T4); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); + T4 param4 = MarshalHelper.ToManagedUnbox(paramPtrs[3]); deleg(param1, param2, param3, param4); @@ -683,8 +676,7 @@ namespace FlaxEngine TRet ret = deleg(instancePtr.Target, ref param1); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); return MarshalReturnValue(ref ret); } @@ -694,7 +686,7 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); TRet ret = deleg(instancePtr.Target, param1); @@ -733,10 +725,8 @@ namespace FlaxEngine TRet ret = deleg(instancePtr.Target, ref param1, ref param2); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); return MarshalReturnValue(ref ret); } @@ -746,8 +736,8 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); TRet ret = deleg(instancePtr.Target, param1, param2); @@ -789,12 +779,9 @@ namespace FlaxEngine TRet ret = deleg(instancePtr.Target, ref param1, ref param2, ref param3); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); return MarshalReturnValue(ref ret); } @@ -804,9 +791,9 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); TRet ret = deleg(instancePtr.Target, param1, param2, param3); @@ -851,14 +838,10 @@ namespace FlaxEngine TRet ret = deleg(instancePtr.Target, ref param1, ref param2, ref param3, ref param4); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); - if (types[3].IsByRef) - MarshalHelper.ToNative(ref param4, param4Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[3].IsByRef) MarshalHelper.ToNative(ref param4, param4Ptr); return MarshalReturnValue(ref ret); } @@ -868,10 +851,10 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); - T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)ManagedHandle.FromIntPtr(paramPtrs[3]).Target : default(T4); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); + T4 param4 = MarshalHelper.ToManagedUnbox(paramPtrs[3]); TRet ret = deleg(instancePtr.Target, param1, param2, param3, param4); @@ -943,8 +926,7 @@ namespace FlaxEngine TRet ret = deleg(ref param1); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); return MarshalReturnValue(ref ret); } @@ -954,7 +936,7 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); TRet ret = deleg(param1); @@ -993,10 +975,8 @@ namespace FlaxEngine TRet ret = deleg(ref param1, ref param2); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); return MarshalReturnValue(ref ret); } @@ -1006,8 +986,8 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); TRet ret = deleg(param1, param2); @@ -1049,12 +1029,9 @@ namespace FlaxEngine TRet ret = deleg(ref param1, ref param2, ref param3); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); return MarshalReturnValue(ref ret); } @@ -1064,9 +1041,9 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); TRet ret = deleg(param1, param2, param3); @@ -1111,14 +1088,10 @@ namespace FlaxEngine TRet ret = deleg(ref param1, ref param2, ref param3, ref param4); // Marshal reference parameters back to original unmanaged references - if (types[0].IsByRef) - MarshalHelper.ToNative(ref param1, param1Ptr); - if (types[1].IsByRef) - MarshalHelper.ToNative(ref param2, param2Ptr); - if (types[2].IsByRef) - MarshalHelper.ToNative(ref param3, param3Ptr); - if (types[3].IsByRef) - MarshalHelper.ToNative(ref param4, param4Ptr); + if (types[0].IsByRef) MarshalHelper.ToNative(ref param1, param1Ptr); + if (types[1].IsByRef) MarshalHelper.ToNative(ref param2, param2Ptr); + if (types[2].IsByRef) MarshalHelper.ToNative(ref param3, param3Ptr); + if (types[3].IsByRef) MarshalHelper.ToNative(ref param4, param4Ptr); return MarshalReturnValue(ref ret); } @@ -1128,10 +1101,10 @@ namespace FlaxEngine { ThunkInvokerDelegate deleg = Unsafe.As(delegateContext); - T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1); - T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)ManagedHandle.FromIntPtr(paramPtrs[1]).Target : default(T2); - T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)ManagedHandle.FromIntPtr(paramPtrs[2]).Target : default(T3); - T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)ManagedHandle.FromIntPtr(paramPtrs[3]).Target : default(T4); + T1 param1 = MarshalHelper.ToManagedUnbox(paramPtrs[0]); + T2 param2 = MarshalHelper.ToManagedUnbox(paramPtrs[1]); + T3 param3 = MarshalHelper.ToManagedUnbox(paramPtrs[2]); + T4 param4 = MarshalHelper.ToManagedUnbox(paramPtrs[3]); TRet ret = deleg(param1, param2, param3, param4); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 811d334e5..e224119f0 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1051,7 +1051,7 @@ namespace Flax.Build.Bindings contents.AppendLine(); contents.AppendLine(" {"); #if USE_NETCORE - contents.AppendLine(String.Format(" SCRIPTING_EXPORT(\"{0}\")", caller.FullNameManaged + "::Internal_" + functionInfo.UniqueName)); + contents.AppendLine(string.Format(" SCRIPTING_EXPORT(\"{0}\")", caller.FullNameManaged + "::Internal_" + functionInfo.UniqueName)); #endif if (!functionInfo.IsStatic) contents.AppendLine(" if (obj == nullptr) DebugLog::ThrowNullReference();"); @@ -1161,8 +1161,8 @@ namespace Flax.Build.Bindings #if USE_NETCORE if (!string.IsNullOrEmpty(callReturnCount)) { - contents.Append(" ").Append("const auto& callTemp = ").Append(string.Format(callFormat, call, callParams)).Append(";").AppendLine(); - call = "callTemp"; + contents.Append(" ").Append("const auto& __callTemp = ").Append(string.Format(callFormat, call, callParams)).Append(";").AppendLine(); + call = "__callTemp"; contents.Append(string.Format(callReturnCount, call)); contents.AppendLine(); contents.Append(callBegin); @@ -1217,7 +1217,7 @@ namespace Flax.Build.Bindings if (apiType.IsStruct && !apiType.IsPod) { CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MClass.h"); - contents.AppendFormat(" {{ auto _temp = {1}; mono_gc_wbarrier_value_copy({0}, &_temp, 1, {2}::TypeInitializer.GetType().ManagedClass->GetNative()); }}", parameterInfo.Name, value, apiType.FullNameNative).AppendLine(); + contents.AppendFormat(" {{ auto __temp = {1}; mono_gc_wbarrier_value_copy({0}, &__temp, 1, {2}::TypeInitializer.GetType().ManagedClass->GetNative()); }}", parameterInfo.Name, value, apiType.FullNameNative).AppendLine(); continue; } } @@ -1774,7 +1774,7 @@ namespace Flax.Build.Bindings contents.Append("bool bind)").AppendLine(); contents.Append(" {").AppendLine(); #if USE_NETCORE - contents.AppendLine(String.Format(" SCRIPTING_EXPORT(\"{0}\")", classTypeNameManagedInternalCall + "::Internal_" + eventInfo.Name + "_Bind")); + contents.AppendLine(string.Format(" SCRIPTING_EXPORT(\"{0}\")", classTypeNameManagedInternalCall + "::Internal_" + eventInfo.Name + "_Bind")); #endif contents.Append(" Function