Merge branch 'GoaLitiuM-dotnet7' into dotnet7

This commit is contained in:
Wojciech Figat
2023-01-02 11:21:17 +01:00
6 changed files with 687 additions and 454 deletions

View File

@@ -391,8 +391,8 @@ namespace FlaxEditor.Content.Import
MaxSize = managed.MaxSize,
TextureGroup = managed.TextureGroup,
Size = managed.Size,
SpriteAreas = managed.SpriteAreas?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteAreas)))) : IntPtr.Zero,
SpriteNames = managed.SpriteNames?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteNames)))) : IntPtr.Zero,
SpriteAreas = managed.SpriteAreas?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteAreas)))) : IntPtr.Zero,
SpriteNames = managed.SpriteNames?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.SpriteNames)))) : IntPtr.Zero,
};
}
internal static void Free(InternalOptionsNative unmanaged)

View File

@@ -265,7 +265,7 @@ namespace FlaxEngine
internal static partial bool Internal_HasConnection(ref AnimationGraph.CustomNode.Context context, int boxId);
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_GetInputValue")]
[return: MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))]
[return: MarshalUsing(typeof(FlaxEngine.ManagedHandleMarshaller))]
internal static partial object Internal_GetInputValue(ref AnimationGraph.CustomNode.Context context, int boxId);
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData")]

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,7 @@
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
#if USE_NETCORE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -15,40 +13,64 @@ namespace FlaxEngine
{
internal unsafe static partial class NativeInterop
{
/// <summary>
/// Helper class for invoking managed methods from delegates.
/// </summary>
internal static class Invoker
{
internal delegate IntPtr MarshalAndInvokeDelegate(object delegateContext, IntPtr instancePtr, IntPtr paramPtr);
internal delegate IntPtr InvokeThunkDelegate(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs);
internal delegate IntPtr MarshalAndInvokeDelegate(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr);
internal delegate IntPtr InvokeThunkDelegate(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs);
/// <summary>
/// Casts managed pointer to unmanaged pointer.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T* ToPointer<T>(IntPtr ptr) where T : unmanaged
{
return (T*)ptr.ToPointer();
}
internal static MethodInfo ToPointerMethod = typeof(Invoker).GetMethod(nameof(Invoker.ToPointer), BindingFlags.Static | BindingFlags.NonPublic);
/// <summary>
/// Creates a delegate for invoker to pass parameters as references.
/// </summary>
internal static Delegate CreateDelegateFromMethod(MethodInfo method, bool byRefParameters = true)
internal static Delegate CreateDelegateFromMethod(MethodInfo method, bool passParametersByRef = true)
{
Type[] methodParameters = method.GetParameters().Select(x => x.ParameterType).ToArray();
Type[] delegateParameters = method.GetParameters().Select(x => x.ParameterType.IsPointer ? typeof(IntPtr) : x.ParameterType).ToArray();
if (byRefParameters)
delegateParameters = delegateParameters.Select(x => x.IsByRef ? x : x.MakeByRefType()).ToArray();
Type[] methodParameters;
if (method.IsStatic)
methodParameters = method.GetParameters().Select(x => x.ParameterType).ToArray();
else
methodParameters = method.GetParameters().Select(x => x.ParameterType).Prepend(method.DeclaringType).ToArray();
List<ParameterExpression> parameterExpressions = new List<ParameterExpression>(delegateParameters.Select(x => Expression.Parameter(x)));
List<Expression> callExpressions = new List<Expression>(parameterExpressions);
for (int i = 0; i < callExpressions.Count; i++)
if (methodParameters[i].IsPointer)
callExpressions[i] = Expression.Call(null, typeof(Invoker).GetMethod(nameof(Invoker.ToPointer), BindingFlags.Static | BindingFlags.NonPublic).MakeGenericMethod(methodParameters[i].GetElementType()), parameterExpressions[i]);
// Pass delegate parameters by reference
Type[] delegateParameters = methodParameters.Select(x => x.IsPointer ? typeof(IntPtr) : x)
.Select(x => passParametersByRef && !x.IsByRef ? x.MakeByRefType() : x).ToArray();
if (!method.IsStatic && passParametersByRef)
delegateParameters[0] = method.DeclaringType;
var firstParamExp = Expression.Parameter(method.DeclaringType);
var callDelegExp = Expression.Call(!method.IsStatic ? firstParamExp : null, method, callExpressions.ToArray());
// Convert unmanaged pointer parameters to IntPtr
ParameterExpression[] parameterExpressions = delegateParameters.Select(x => Expression.Parameter(x)).ToArray();
Expression[] callExpressions = new Expression[methodParameters.Length];
for (int i = 0; i < methodParameters.Length; i++)
{
Type parameterType = methodParameters[i];
if (parameterType.IsPointer)
{
callExpressions[i] =
Expression.Call(null, ToPointerMethod.MakeGenericMethod(parameterType.GetElementType()), parameterExpressions[i]);
}
else
callExpressions[i] = parameterExpressions[i];
}
if (!method.IsStatic)
parameterExpressions.Insert(0, firstParamExp);
var lambda = Expression.Lambda(callDelegExp, parameterExpressions.ToArray());
return lambda.Compile();
// Create and compile the delegate
MethodCallExpression callDelegExp;
if (method.IsStatic)
callDelegExp = Expression.Call(null, method, callExpressions.ToArray());
else
callDelegExp = Expression.Call(parameterExpressions[0], method, callExpressions.Skip(1).ToArray());
Type delegateType = DelegateHelpers.MakeNewCustomDelegate(delegateParameters.Append(method.ReturnType).ToArray());
return Expression.Lambda(delegateType, callDelegExp, parameterExpressions.ToArray()).Compile();
}
internal static IntPtr MarshalReturnValue<TRet>(ref TRet returnValue)
@@ -57,25 +79,26 @@ namespace FlaxEngine
return ManagedString.ToNative(Unsafe.As<string>(returnValue));
else if (typeof(TRet) == typeof(IntPtr))
return (IntPtr)(object)returnValue;
else if (typeof(TRet) == typeof(ManagedHandle))
return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnValue);
else if (typeof(TRet) == typeof(bool))
return (bool)(object)returnValue ? boolTruePtr : boolFalsePtr;
else if (typeof(TRet) == typeof(Type))
return returnValue != null ? GCHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As<Type>(returnValue))) : IntPtr.Zero;
return returnValue != null ? ManagedHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As<Type>(returnValue))) : IntPtr.Zero;
else if (typeof(TRet).IsArray)
{
if (returnValue == null)
return IntPtr.Zero;
var elementType = typeof(TRet).GetElementType();
if (ArrayFactory.GetMarshalledType(elementType) == elementType)
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnValue)), GCHandleType.Weak));
return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnValue)), GCHandleType.Weak));
else
return GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<Array>(returnValue))), GCHandleType.Weak));
return ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(ManagedArrayToGCHandleArray(Unsafe.As<Array>(returnValue))), GCHandleType.Weak));
}
else
return returnValue != null ? GCHandle.ToIntPtr(GCHandle.Alloc(returnValue, GCHandleType.Weak)) : IntPtr.Zero;
return returnValue != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(returnValue, GCHandleType.Weak)) : IntPtr.Zero;
}
internal static class InvokerNoRet0<TInstance>
{
internal delegate void InvokerDelegate(object instance);
@@ -92,21 +115,21 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
deleg(GCHandle.FromIntPtr(instancePtr).Target);
deleg(instancePtr.Target);
return IntPtr.Zero;
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
deleg(GCHandle.FromIntPtr(instancePtr).Target);
deleg(instancePtr.Target);
return IntPtr.Zero;
}
@@ -128,7 +151,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -137,7 +160,7 @@ namespace FlaxEngine
T1 param1 = default;
if (param1Ptr != IntPtr.Zero) MarshalHelper<T1>.ToManaged(ref param1, param1Ptr, types[0].IsByRef);
deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1);
deleg(instancePtr.Target, ref param1);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -147,13 +170,13 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1);
deleg(instancePtr.Target, param1);
return IntPtr.Zero;
}
@@ -175,7 +198,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -187,7 +210,7 @@ namespace FlaxEngine
if (param1Ptr != IntPtr.Zero) MarshalHelper<T1>.ToManaged(ref param1, param1Ptr, types[0].IsByRef);
if (param2Ptr != IntPtr.Zero) MarshalHelper<T2>.ToManaged(ref param2, param2Ptr, types[1].IsByRef);
deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1, ref param2);
deleg(instancePtr.Target, ref param1, ref param2);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -199,14 +222,14 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
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);
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2);
deleg(instancePtr.Target, param1, param2);
return IntPtr.Zero;
}
@@ -228,7 +251,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -243,7 +266,7 @@ namespace FlaxEngine
if (param2Ptr != IntPtr.Zero) MarshalHelper<T2>.ToManaged(ref param2, param2Ptr, types[1].IsByRef);
if (param3Ptr != IntPtr.Zero) MarshalHelper<T3>.ToManaged(ref param3, param3Ptr, types[2].IsByRef);
deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1, ref param2, ref param3);
deleg(instancePtr.Target, ref param1, ref param2, ref param3);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -257,15 +280,15 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
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);
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3);
deleg(instancePtr.Target, param1, param2, param3);
return IntPtr.Zero;
}
@@ -287,7 +310,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -305,7 +328,7 @@ namespace FlaxEngine
if (param3Ptr != IntPtr.Zero) MarshalHelper<T3>.ToManaged(ref param3, param3Ptr, types[2].IsByRef);
if (param4Ptr != IntPtr.Zero) MarshalHelper<T4>.ToManaged(ref param4, param4Ptr, types[3].IsByRef);
deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1, ref param2, ref param3, ref param4);
deleg(instancePtr.Target, ref param1, ref param2, ref param3, ref param4);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -321,16 +344,16 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)GCHandle.FromIntPtr(paramPtrs[3]).Target : default(T4);
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);
deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3, param4);
deleg(instancePtr.Target, param1, param2, param3, param4);
return IntPtr.Zero;
}
@@ -352,7 +375,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -362,7 +385,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -388,7 +411,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -407,11 +430,11 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
deleg(param1);
@@ -435,7 +458,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -459,12 +482,12 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
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);
deleg(param1, param2);
@@ -488,7 +511,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -517,13 +540,13 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
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);
deleg(param1, param2, param3);
@@ -547,7 +570,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -581,14 +604,14 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)GCHandle.FromIntPtr(paramPtrs[3]).Target : default(T4);
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);
deleg(param1, param2, param3, param4);
@@ -612,21 +635,21 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target);
TRet ret = deleg(instancePtr.Target);
return MarshalReturnValue(ref ret);
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target);
TRet ret = deleg(instancePtr.Target);
return MarshalReturnValue(ref ret);
}
@@ -648,7 +671,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -657,7 +680,7 @@ namespace FlaxEngine
T1 param1 = default;
if (param1Ptr != IntPtr.Zero) MarshalHelper<T1>.ToManaged(ref param1, param1Ptr, types[0].IsByRef);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1);
TRet ret = deleg(instancePtr.Target, ref param1);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -667,13 +690,13 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1);
TRet ret = deleg(instancePtr.Target, param1);
return MarshalReturnValue(ref ret);
}
@@ -695,7 +718,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -707,7 +730,7 @@ namespace FlaxEngine
if (param1Ptr != IntPtr.Zero) MarshalHelper<T1>.ToManaged(ref param1, param1Ptr, types[0].IsByRef);
if (param2Ptr != IntPtr.Zero) MarshalHelper<T2>.ToManaged(ref param2, param2Ptr, types[1].IsByRef);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1, ref param2);
TRet ret = deleg(instancePtr.Target, ref param1, ref param2);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -719,14 +742,14 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
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);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2);
TRet ret = deleg(instancePtr.Target, param1, param2);
return MarshalReturnValue(ref ret);
}
@@ -748,7 +771,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -763,7 +786,7 @@ namespace FlaxEngine
if (param2Ptr != IntPtr.Zero) MarshalHelper<T2>.ToManaged(ref param2, param2Ptr, types[1].IsByRef);
if (param3Ptr != IntPtr.Zero) MarshalHelper<T3>.ToManaged(ref param3, param3Ptr, types[2].IsByRef);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1, ref param2, ref param3);
TRet ret = deleg(instancePtr.Target, ref param1, ref param2, ref param3);
// Marshal reference parameters back to original unmanaged references
if (types[0].IsByRef)
@@ -777,15 +800,15 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
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);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3);
TRet ret = deleg(instancePtr.Target, param1, param2, param3);
return MarshalReturnValue(ref ret);
}
@@ -807,7 +830,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -825,7 +848,7 @@ namespace FlaxEngine
if (param3Ptr != IntPtr.Zero) MarshalHelper<T3>.ToManaged(ref param3, param3Ptr, types[2].IsByRef);
if (param4Ptr != IntPtr.Zero) MarshalHelper<T4>.ToManaged(ref param4, param4Ptr, types[3].IsByRef);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, ref param1, ref param2, ref param3, ref param4);
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)
@@ -841,16 +864,16 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)GCHandle.FromIntPtr(paramPtrs[3]).Target : default(T4);
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);
TRet ret = deleg(GCHandle.FromIntPtr(instancePtr).Target, param1, param2, param3, param4);
TRet ret = deleg(instancePtr.Target, param1, param2, param3, param4);
return MarshalReturnValue(ref ret);
}
@@ -872,7 +895,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -882,7 +905,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
@@ -908,7 +931,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -927,11 +950,11 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)ManagedHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
TRet ret = deleg(param1);
@@ -955,7 +978,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -979,12 +1002,12 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
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);
TRet ret = deleg(param1, param2);
@@ -1008,7 +1031,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -1037,13 +1060,13 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
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);
TRet ret = deleg(param1, param2, param3);
@@ -1067,7 +1090,7 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static IntPtr MarshalAndInvoke(object delegateContext, IntPtr instancePtr, IntPtr paramPtr)
internal static IntPtr MarshalAndInvoke(object delegateContext, ManagedHandle instancePtr, IntPtr paramPtr)
{
(Type[] types, InvokerDelegate deleg) = (Tuple<Type[], InvokerDelegate>)(delegateContext);
@@ -1101,14 +1124,14 @@ namespace FlaxEngine
}
[DebuggerStepThrough]
internal static unsafe IntPtr InvokeThunk(object delegateContext, IntPtr instancePtr, IntPtr* paramPtrs)
internal static unsafe IntPtr InvokeThunk(object delegateContext, ManagedHandle instancePtr, IntPtr* paramPtrs)
{
ThunkInvokerDelegate deleg = Unsafe.As<ThunkInvokerDelegate>(delegateContext);
T1 param1 = paramPtrs[0] != IntPtr.Zero ? (T1)GCHandle.FromIntPtr(paramPtrs[0]).Target : default(T1);
T2 param2 = paramPtrs[1] != IntPtr.Zero ? (T2)GCHandle.FromIntPtr(paramPtrs[1]).Target : default(T2);
T3 param3 = paramPtrs[2] != IntPtr.Zero ? (T3)GCHandle.FromIntPtr(paramPtrs[2]).Target : default(T3);
T4 param4 = paramPtrs[3] != IntPtr.Zero ? (T4)GCHandle.FromIntPtr(paramPtrs[3]).Target : default(T4);
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);
TRet ret = deleg(param1, param2, param3, param4);

View File

@@ -209,15 +209,15 @@ namespace FlaxEngine
return result;
}
internal static IntPtr VersionToManaged(int major, int minor, int build, int revision)
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));
return GCHandle.ToIntPtr(GCHandle.Alloc(version));
return ManagedHandle.Alloc(version);
}
internal static void VersionToNative(IntPtr versionHandle, IntPtr nativePtr)
internal static void VersionToNative(ManagedHandle versionHandle, IntPtr nativePtr)
{
Version version = (Version)GCHandle.FromIntPtr(versionHandle).Target;
Version version = Unsafe.As<Version>(versionHandle.Target);
if (version != null)
{
Marshal.WriteInt32(nativePtr, 0, version.Major);

View File

@@ -486,7 +486,7 @@ namespace Flax.Build.Bindings
else if (returnValueType == "CultureInfo")
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.CultureInfoMarshaller))";
else if (functionInfo.ReturnType.Type == "Variant")
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))";
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.ManagedHandleMarshaller))";
else if (FindApiTypeInfo(buildData, functionInfo.ReturnType, caller)?.IsInterface ?? false)
{
// Interfaces are not supported by NativeMarshallingAttribute, marshal the parameter
@@ -538,7 +538,7 @@ namespace Flax.Build.Bindings
else if (parameterInfo.Type.Type == "CultureInfo")
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.CultureInfoMarshaller))";
else if (parameterInfo.Type.Type == "Variant") // object
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))";
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.ManagedHandleMarshaller))";
else if (parameterInfo.Type.Type == "MonoArray")
parameterMarshalType = "MarshalUsing(typeof(FlaxEngine.SystemArrayMarshaller))";
else if (parameterInfo.Type.Type == "Array" && parameterInfo.Type.GenericArgs.Count > 0 && parameterInfo.Type.GenericArgs[0].Type == "bool")
@@ -1263,30 +1263,30 @@ namespace Flax.Build.Bindings
#pragma warning disable 1591
public static class NativeToManaged
{
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => ({{classInfo.Name}})GCHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged);
public static void Free(IntPtr unmanaged) => GCHandleMarshaller.NativeToManaged.Free(unmanaged);
public static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => ({{classInfo.Name}})ManagedHandleMarshaller.NativeToManaged.ConvertToManaged(unmanaged);
public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.NativeToManaged.Free(unmanaged);
}
public static class ManagedToNative
{
public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => GCHandleMarshaller.ManagedToNative.ConvertToUnmanaged(managed);
public static void Free(IntPtr unmanaged) => GCHandleMarshaller.ManagedToNative.Free(unmanaged);
public static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => ManagedHandleMarshaller.ManagedToNative.ConvertToUnmanaged(managed);
public static void Free(IntPtr unmanaged) => ManagedHandleMarshaller.ManagedToNative.Free(unmanaged);
}
[HideInEditor]
public struct Bidirectional
{
GCHandleMarshaller.Bidirectional marsh;
ManagedHandleMarshaller.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() => ({{classInfo.Name}})marsh.ToManaged();
public void Free() => marsh.Free();
}
internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => ({{classInfo.Name}})GCHandleMarshaller.ConvertToManaged(unmanaged);
internal static IntPtr ConvertToUnmanaged({{classInfo.Name}} managed) => GCHandleMarshaller.ConvertToUnmanaged(managed);
internal static void Free(IntPtr unmanaged) => GCHandleMarshaller.Free(unmanaged);
internal static {{classInfo.Name}} ConvertToManaged(IntPtr unmanaged) => ({{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}} ToManaged(IntPtr managed) => ({{classInfo.Name}})GCHandleMarshaller.ToManaged(managed);
internal static IntPtr ToNative({{classInfo.Name}} managed) => GCHandleMarshaller.ToNative(managed);
internal static {{classInfo.Name}} ToManaged(IntPtr managed) => ({{classInfo.Name}})ManagedHandleMarshaller.ToManaged(managed);
internal static IntPtr ToNative({{classInfo.Name}} managed) => ManagedHandleMarshaller.ToNative(managed);
#pragma warning restore 1591
}
""").Split(new char[] { '\n' })));
@@ -1465,41 +1465,41 @@ namespace Flax.Build.Bindings
if (fieldInfo.Type.IsObjectRef)
{
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({fieldInfo.Type.GenericArgs[0].Type})GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({fieldInfo.Type.GenericArgs[0].Type})ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
// Permanent ScriptingObject handle is passed from native side, do not release it
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
}
else if (fieldInfo.Type.Type == "ScriptingObject")
{
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? (FlaxEngine.Object)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? (FlaxEngine.Object)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
// Permanent ScriptingObject handle is passed from native side, do not release it
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
}
else if (fieldInfo.Type.IsPtr && originalType != "IntPtr" && !originalType.EndsWith("*"))
{
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"managed.{fieldInfo.Name} != null ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
// Permanent ScriptingObject handle is passed from native side, do not release it
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
//freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
}
else if (fieldInfo.Type.Type == "Dictionary")
{
string dictionaryArgs = String.Join(", ",
fieldInfo.Type.GenericArgs.Select(x => CSharpNativeToManagedBasicTypes.ContainsKey(x.Type) ? CSharpNativeToManagedBasicTypes[x.Type] : x.Type).ToArray());
toManagedContent.Append(
$"managed.{fieldInfo.Name} != IntPtr.Zero ? (System.Collections.Generic.{fieldInfo.Type.Type}<{dictionaryArgs}>)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
$"managed.{fieldInfo.Name} != IntPtr.Zero ? (System.Collections.Generic.{fieldInfo.Type.Type}<{dictionaryArgs}>)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append(
$"GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
$"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
}
else if (fieldInfo.Type.Type == "Array")
{
@@ -1509,34 +1509,34 @@ namespace Flax.Build.Bindings
// Marshal blittable array elements back to original non-blittable elements
string originalElementTypeMarshaller = originalElementType + "Marshaller";
string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType}Internal";
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.NativeArrayToManagedArray<{originalElementType}, {internalElementType}>(((ManagedArray)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).GetSpan<{internalElementType}>(), {originalElementTypeMarshaller}.ToManaged) : null");
toNativeContent.Append($"GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak))");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).GetSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).GetSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.NativeArrayToManagedArray<{originalElementType}, {internalElementType}>(((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).GetSpan<{internalElementType}>(), {originalElementTypeMarshaller}.ToManaged) : null");
toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak))");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).GetSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<{internalElementType}> values = ((ManagedArray)handle.Target).GetSpan<{internalElementType}>(); foreach (var value in values) {{ {originalElementTypeMarshaller}.Free(value); }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
}
else if (fieldInfo.Type.GenericArgs[0].IsObjectRef)
{
// Array elements passed as GCHandles
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null");
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).GetSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ GCHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).GetSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ GCHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.GCHandleArrayToManagedArray<{originalElementType}>((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target) : null");
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(NativeInterop.ManagedArrayToGCHandleArray(managed.{fieldInfo.Name})), GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).GetSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); Span<IntPtr> ptrs = ((ManagedArray)handle.Target).GetSpan<IntPtr>(); foreach (var ptr in ptrs) {{ if (ptr != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(ptr).Free(); }} }} ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
}
else
{
// Blittable array elements
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ((ManagedArray)GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).GetArray<{originalElementType}>() : null");
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? GCHandle.ToIntPtr(GCHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle handle = GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ((ManagedArray)ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target).GetArray<{originalElementType}>() : null");
toNativeContent.Append($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedHandle.Alloc(ManagedArray.WrapNewArray(managed.{fieldInfo.Name}), GCHandleType.Weak)) : IntPtr.Zero");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}); ((ManagedArray)handle.Target).Free(); handle.Free(); }}");
}
}
else if (fieldInfo.Type.Type == "Version")
{
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})GCHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"GCHandle.ToIntPtr(GCHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ GCHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
toManagedContent.Append($"managed.{fieldInfo.Name} != IntPtr.Zero ? ({originalType})ManagedHandle.FromIntPtr(managed.{fieldInfo.Name}).Target : null");
toNativeContent.Append($"ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managed.{fieldInfo.Name}, GCHandleType.Weak))");
freeContents.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
freeContents2.AppendLine($"if (unmanaged.{fieldInfo.Name} != IntPtr.Zero) {{ ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Free(); }}");
}
else if (originalType == "string")
{
@@ -1930,9 +1930,9 @@ namespace Flax.Build.Bindings
contents.Append(indent).AppendLine($"public static class {marshallerName}");
contents.Append(indent).AppendLine("{");
contents.AppendLine("#pragma warning disable 1591");
contents.Append(indent).Append(" ").AppendLine($"internal static {interfaceInfo.Name} ConvertToManaged(IntPtr unmanaged) => ({interfaceInfo.Name})GCHandleMarshaller.ConvertToManaged(unmanaged);");
contents.Append(indent).Append(" ").AppendLine($"internal static IntPtr ConvertToUnmanaged({interfaceInfo.Name} managed) => GCHandleMarshaller.ConvertToUnmanaged(managed);");
contents.Append(indent).Append(" ").AppendLine("internal static void Free(IntPtr unmanaged) => GCHandleMarshaller.Free(unmanaged);");
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("}");
}