Merge branch 'marshalling_scriptingobject_changes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-marshalling_scriptingobject_changes
# Conflicts: # Source/Engine/Engine/NativeInterop.Unmanaged.cs # Source/Engine/Scripting/Runtime/DotNet.cpp
This commit is contained in:
@@ -84,7 +84,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
internal static IntPtr MarshalReturnValueType(ref Type returnValue)
|
||||
{
|
||||
return returnValue != null ? ManagedHandle.ToIntPtr(GetTypeGCHandle(returnValue)) : IntPtr.Zero;
|
||||
return returnValue != null ? ManagedHandle.ToIntPtr(GetTypeManagedHandle(returnValue)) : IntPtr.Zero;
|
||||
}
|
||||
|
||||
internal static IntPtr MarshalReturnValueArray<TRet>(ref TRet returnValue)
|
||||
@@ -162,8 +162,8 @@ namespace FlaxEngine.Interop
|
||||
return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnObject);
|
||||
if (returnType == typeof(bool))
|
||||
return (bool)returnObject ? boolTruePtr : boolFalsePtr;
|
||||
if (returnType == typeof(Type))
|
||||
return ManagedHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As<Type>(returnObject)));
|
||||
if (returnType == typeof(Type) || returnType == typeof(TypeHolder))
|
||||
return ManagedHandle.ToIntPtr(GetTypeManagedHandle(Unsafe.As<Type>(returnObject)));
|
||||
if (returnType.IsArray && ArrayFactory.GetMarshalledType(returnType.GetElementType()) == returnType.GetElementType())
|
||||
return ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(Unsafe.As<Array>(returnObject)), GCHandleType.Weak);
|
||||
if (returnType.IsArray)
|
||||
@@ -186,8 +186,8 @@ namespace FlaxEngine.Interop
|
||||
return (IntPtr)(object)returnObject;
|
||||
if (returnType == typeof(ManagedHandle))
|
||||
return ManagedHandle.ToIntPtr((ManagedHandle)(object)returnObject);
|
||||
if (returnType == typeof(Type))
|
||||
return returnObject != null ? ManagedHandle.ToIntPtr(GetTypeGCHandle(Unsafe.As<Type>(returnObject))) : IntPtr.Zero;
|
||||
if (returnType == typeof(Type) || returnType == typeof(TypeHolder))
|
||||
return returnObject != null ? ManagedHandle.ToIntPtr(GetTypeManagedHandle(Unsafe.As<Type>(returnObject))) : IntPtr.Zero;
|
||||
if (returnType.IsArray)
|
||||
{
|
||||
var elementType = returnType.GetElementType();
|
||||
|
||||
@@ -119,13 +119,13 @@ namespace FlaxEngine.Interop
|
||||
[CustomMarshaller(typeof(Type), MarshalMode.Default, typeof(SystemTypeMarshaller))]
|
||||
public static class SystemTypeMarshaller
|
||||
{
|
||||
public static Type ConvertToManaged(IntPtr unmanaged) => Unsafe.As<Type>(ManagedHandleMarshaller.ConvertToManaged(unmanaged));
|
||||
public static Type ConvertToManaged(IntPtr unmanaged) => unmanaged != IntPtr.Zero ? Unsafe.As<FlaxEngine.Interop.NativeInterop.TypeHolder>(ManagedHandleMarshaller.ConvertToManaged(unmanaged)).type : null;
|
||||
|
||||
public static IntPtr ConvertToUnmanaged(Type managed)
|
||||
{
|
||||
if (managed == null)
|
||||
return IntPtr.Zero;
|
||||
ManagedHandle handle = NativeInterop.GetTypeGCHandle(managed);
|
||||
ManagedHandle handle = NativeInterop.GetTypeManagedHandle(managed);
|
||||
return ManagedHandle.ToIntPtr(handle);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace FlaxEngine.Interop
|
||||
internal struct NativeClassDefinitions
|
||||
{
|
||||
internal ManagedHandle typeHandle;
|
||||
internal IntPtr nativePointer;
|
||||
internal IntPtr name;
|
||||
internal IntPtr fullname;
|
||||
internal IntPtr @namespace;
|
||||
@@ -40,6 +41,7 @@ namespace FlaxEngine.Interop
|
||||
internal IntPtr name;
|
||||
internal ManagedHandle fieldHandle;
|
||||
internal ManagedHandle fieldTypeHandle;
|
||||
internal int fieldOffset;
|
||||
internal uint fieldAttributes;
|
||||
}
|
||||
|
||||
@@ -139,6 +141,9 @@ namespace FlaxEngine.Interop
|
||||
|
||||
unsafe partial class NativeInterop
|
||||
{
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "NativeInterop_CreateClass", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial void NativeInterop_CreateClass(ref NativeClassDefinitions managedClass, ManagedHandle assemblyHandle);
|
||||
|
||||
internal enum MTypes : uint
|
||||
{
|
||||
End = 0x00,
|
||||
@@ -205,46 +210,8 @@ namespace FlaxEngine.Interop
|
||||
NativeMemory.AlignedFree(ptr);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetManagedClasses(ManagedHandle assemblyHandle, NativeClassDefinitions** managedClasses, int* managedClassCount)
|
||||
private static Assembly GetOwningAssembly(Type type)
|
||||
{
|
||||
Assembly assembly = Unsafe.As<Assembly>(assemblyHandle.Target);
|
||||
var assemblyTypes = GetAssemblyTypes(assembly);
|
||||
|
||||
NativeClassDefinitions* arr = (NativeClassDefinitions*)NativeAlloc(assemblyTypes.Length, Unsafe.SizeOf<NativeClassDefinitions>());
|
||||
|
||||
for (int i = 0; i < assemblyTypes.Length; i++)
|
||||
{
|
||||
var type = assemblyTypes[i];
|
||||
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeClassDefinitions>() * i);
|
||||
var managedClass = new NativeClassDefinitions
|
||||
{
|
||||
typeHandle = GetTypeGCHandle(type),
|
||||
name = NativeAllocStringAnsi(type.Name),
|
||||
fullname = NativeAllocStringAnsi(type.GetTypeName()),
|
||||
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
|
||||
typeAttributes = (uint)type.Attributes,
|
||||
};
|
||||
Unsafe.Write(ptr.ToPointer(), managedClass);
|
||||
}
|
||||
|
||||
*managedClasses = arr;
|
||||
*managedClassCount = assemblyTypes.Length;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetManagedClassFromType(ManagedHandle typeHandle, NativeClassDefinitions* managedClass, ManagedHandle* assemblyHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
*managedClass = new NativeClassDefinitions
|
||||
{
|
||||
typeHandle = GetTypeGCHandle(type),
|
||||
name = NativeAllocStringAnsi(type.Name),
|
||||
fullname = NativeAllocStringAnsi(type.GetTypeName()),
|
||||
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
|
||||
typeAttributes = (uint)type.Attributes,
|
||||
};
|
||||
|
||||
Assembly assembly = null;
|
||||
if (type.IsGenericType && !type.Assembly.IsCollectible)
|
||||
{
|
||||
@@ -261,14 +228,87 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
if (assembly == null)
|
||||
assembly = type.Assembly;
|
||||
return assembly;
|
||||
}
|
||||
|
||||
*assemblyHandle = GetAssemblyHandle(assembly);
|
||||
private static NativeClassDefinitions CreateNativeClassDefinitions(Type type, out ManagedHandle assemblyHandle)
|
||||
{
|
||||
assemblyHandle = GetAssemblyHandle(GetOwningAssembly(type));
|
||||
return CreateNativeClassDefinitions(type);
|
||||
}
|
||||
|
||||
private static NativeClassDefinitions CreateNativeClassDefinitions(Type type)
|
||||
{
|
||||
return new NativeClassDefinitions()
|
||||
{
|
||||
typeHandle = RegisterType(type).handle,
|
||||
name = NativeAllocStringAnsi(type.Name),
|
||||
fullname = NativeAllocStringAnsi(type.GetTypeName()),
|
||||
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
|
||||
typeAttributes = (uint)type.Attributes,
|
||||
};
|
||||
}
|
||||
|
||||
private static NativeClassDefinitions CreateNativeClassDefinitions(Type type, ManagedHandle typeHandle, out ManagedHandle assemblyHandle)
|
||||
{
|
||||
assemblyHandle = GetAssemblyHandle(GetOwningAssembly(type));
|
||||
return new NativeClassDefinitions()
|
||||
{
|
||||
typeHandle = typeHandle,
|
||||
name = NativeAllocStringAnsi(type.Name),
|
||||
fullname = NativeAllocStringAnsi(type.GetTypeName()),
|
||||
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
|
||||
typeAttributes = (uint)type.Attributes,
|
||||
};
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetManagedClasses(ManagedHandle assemblyHandle, NativeClassDefinitions** managedClasses, int* managedClassCount)
|
||||
{
|
||||
Assembly assembly = Unsafe.As<Assembly>(assemblyHandle.Target);
|
||||
Type[] assemblyTypes = GetAssemblyTypes(assembly);
|
||||
|
||||
*managedClasses = (NativeClassDefinitions*)NativeAlloc(assemblyTypes.Length, Unsafe.SizeOf<NativeClassDefinitions>());
|
||||
*managedClassCount = assemblyTypes.Length;
|
||||
Span<NativeClassDefinitions> span = new Span<NativeClassDefinitions>(*managedClasses, assemblyTypes.Length);
|
||||
for (int i = 0; i < assemblyTypes.Length; i++)
|
||||
{
|
||||
Type type = assemblyTypes[i];
|
||||
ref var managedClass = ref span[i];
|
||||
managedClass = CreateNativeClassDefinitions(type);
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void RegisterManagedClassNativePointers(NativeClassDefinitions** managedClasses, int managedClassCount)
|
||||
{
|
||||
Span<NativeClassDefinitions> span = new Span<NativeClassDefinitions>(Unsafe.Read<IntPtr>(managedClasses).ToPointer(), managedClassCount);
|
||||
foreach (ref NativeClassDefinitions managedClass in span)
|
||||
{
|
||||
TypeHolder typeHolder = Unsafe.As<TypeHolder>(managedClass.typeHandle.Target);
|
||||
typeHolder.managedClassPointer = managedClass.nativePointer;
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetManagedClassFromType(ManagedHandle typeHandle, NativeClassDefinitions* managedClass, ManagedHandle* assemblyHandle)
|
||||
{
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
*managedClass = CreateNativeClassDefinitions(type, out ManagedHandle handle);
|
||||
*assemblyHandle = handle;
|
||||
}
|
||||
|
||||
private static void RegisterNativeClassFromType(TypeHolder typeHolder, ManagedHandle typeHandle)
|
||||
{
|
||||
NativeClassDefinitions managedClass = CreateNativeClassDefinitions(typeHolder.type, typeHandle, out ManagedHandle assemblyHandle);
|
||||
NativeInterop_CreateClass(ref managedClass, assemblyHandle);
|
||||
typeHolder.managedClassPointer = managedClass.nativePointer;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetClassMethods(ManagedHandle typeHandle, NativeMethodDefinitions** classMethods, int* classMethodsCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
|
||||
var methods = new List<MethodInfo>();
|
||||
var staticMethods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
|
||||
@@ -296,7 +336,7 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetClassFields(ManagedHandle typeHandle, NativeFieldDefinitions** classFields, int* classFieldsCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
var fields = type.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
NativeFieldDefinitions* arr = (NativeFieldDefinitions*)NativeAlloc(fields.Length, Unsafe.SizeOf<NativeFieldDefinitions>());
|
||||
@@ -318,7 +358,8 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
name = NativeAllocStringAnsi(fieldHolder.field.Name),
|
||||
fieldHandle = fieldHandle,
|
||||
fieldTypeHandle = GetTypeGCHandle(fieldHolder.field.FieldType),
|
||||
fieldTypeHandle = GetTypeManagedHandle(fieldHolder.field.FieldType),
|
||||
fieldOffset = fieldHolder.fieldOffset,
|
||||
fieldAttributes = (uint)fieldHolder.field.Attributes,
|
||||
};
|
||||
Unsafe.Write(IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeFieldDefinitions>() * i).ToPointer(), classField);
|
||||
@@ -330,7 +371,7 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetClassProperties(ManagedHandle typeHandle, NativePropertyDefinitions** classProperties, int* classPropertiesCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
var arr = (NativePropertyDefinitions*)NativeAlloc(properties.Length, Unsafe.SizeOf<NativePropertyDefinitions>());
|
||||
@@ -364,7 +405,7 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetClassAttributes(ManagedHandle typeHandle, ManagedHandle** classAttributes, int* classAttributesCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
object[] attributeValues = type.GetCustomAttributes(false);
|
||||
|
||||
ManagedHandle* arr = (ManagedHandle*)NativeAlloc(attributeValues.Length, Unsafe.SizeOf<ManagedHandle>());
|
||||
@@ -384,13 +425,13 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetCustomAttribute(ManagedHandle typeHandle, ManagedHandle attributeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
var attributes = type.GetCustomAttributes(false);
|
||||
object attrib;
|
||||
if (attributeHandle.IsAllocated)
|
||||
{
|
||||
// Check for certain attribute type
|
||||
Type attributeType = Unsafe.As<Type>(attributeHandle.Target);
|
||||
Type attributeType = Unsafe.As<TypeHolder>(attributeHandle.Target);
|
||||
attrib = attributes.FirstOrDefault(x => x.GetType() == attributeType);
|
||||
}
|
||||
else
|
||||
@@ -413,7 +454,7 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void GetClassInterfaces(ManagedHandle typeHandle, IntPtr* classInterfaces, int* classInterfacesCount)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type[] interfaces = type.GetInterfaces();
|
||||
|
||||
// Match mono_class_get_interfaces which doesn't return interfaces from base class
|
||||
@@ -465,7 +506,7 @@ namespace FlaxEngine.Interop
|
||||
IntPtr arr = (IntPtr)NativeAlloc(interfaces.Length, IntPtr.Size);
|
||||
for (int i = 0; i < interfaces.Length; i++)
|
||||
{
|
||||
ManagedHandle handle = GetTypeGCHandle(interfaces[i]);
|
||||
ManagedHandle handle = GetTypeManagedHandle(interfaces[i]);
|
||||
Unsafe.Write<ManagedHandle>(IntPtr.Add(arr, IntPtr.Size * i).ToPointer(), handle);
|
||||
}
|
||||
*classInterfaces = arr;
|
||||
@@ -477,7 +518,7 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
MethodHolder methodHolder = Unsafe.As<MethodHolder>(methodHandle.Target);
|
||||
Type returnType = methodHolder.returnType;
|
||||
return GetTypeGCHandle(returnType);
|
||||
return GetTypeManagedHandle(returnType);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -488,7 +529,7 @@ namespace FlaxEngine.Interop
|
||||
IntPtr arr = (IntPtr)NativeAlloc(methodHolder.parameterTypes.Length, IntPtr.Size);
|
||||
for (int i = 0; i < methodHolder.parameterTypes.Length; i++)
|
||||
{
|
||||
ManagedHandle typeHandle = GetTypeGCHandle(methodHolder.parameterTypes[i]);
|
||||
ManagedHandle typeHandle = GetTypeManagedHandle(methodHolder.parameterTypes[i]);
|
||||
Unsafe.Write<ManagedHandle>(IntPtr.Add(new IntPtr(arr), IntPtr.Size * i).ToPointer(), typeHandle);
|
||||
}
|
||||
*typeHandles = arr;
|
||||
@@ -509,22 +550,15 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle NewObject(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
if (type.IsAbstract)
|
||||
{
|
||||
// Dotnet doesn't allow to instantiate abstract type thus allow to use generated mock class usage (eg. for Script or GPUResource) for generated abstract types
|
||||
var abstractWrapper = type.GetNestedType("AbstractWrapper", BindingFlags.NonPublic);
|
||||
if (abstractWrapper != null)
|
||||
type = abstractWrapper;
|
||||
}
|
||||
object value = RuntimeHelpers.GetUninitializedObject(type);
|
||||
TypeHolder typeHolder = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
object value = typeHolder.CreateObject();
|
||||
return ManagedHandle.Alloc(value);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle NewArray(ManagedHandle typeHandle, long size)
|
||||
{
|
||||
Type elementType = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type elementType = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type marshalledType = ArrayFactory.GetMarshalledType(elementType);
|
||||
Type arrayType = ArrayFactory.GetArrayType(elementType);
|
||||
if (marshalledType.IsValueType)
|
||||
@@ -543,9 +577,9 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetArrayTypeFromElementType(ManagedHandle elementTypeHandle)
|
||||
{
|
||||
Type elementType = Unsafe.As<Type>(elementTypeHandle.Target);
|
||||
Type elementType = Unsafe.As<TypeHolder>(elementTypeHandle.Target);
|
||||
Type classType = ArrayFactory.GetArrayType(elementType);
|
||||
return GetTypeGCHandle(classType);
|
||||
return GetTypeManagedHandle(classType);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -606,7 +640,7 @@ namespace FlaxEngine.Interop
|
||||
Type classType = obj.GetType();
|
||||
if (classType == typeof(ManagedArray))
|
||||
classType = ((ManagedArray)obj).ArrayType;
|
||||
return GetTypeGCHandle(classType);
|
||||
return GetTypeManagedHandle(classType);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -647,7 +681,7 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle BoxValue(ManagedHandle typeHandle, IntPtr valuePtr)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
object value = MarshalToManaged(valuePtr, type);
|
||||
return ManagedHandle.Alloc(value, GCHandleType.Weak);
|
||||
}
|
||||
@@ -690,6 +724,14 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static IntPtr GetObjectClass(ManagedHandle objectHandle)
|
||||
{
|
||||
object obj = objectHandle.Target;
|
||||
TypeHolder typeHolder = GetTypeHolder(obj.GetType());
|
||||
return typeHolder.managedClassPointer;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static IntPtr InvokeMethod(ManagedHandle instanceHandle, ManagedHandle methodHandle, IntPtr paramPtr, IntPtr exceptionPtr)
|
||||
{
|
||||
@@ -706,7 +748,7 @@ namespace FlaxEngine.Interop
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exceptionPtr != IntPtr.Zero)
|
||||
Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(exception, GCHandleType.Weak));
|
||||
Unsafe.Write<IntPtr>(exceptionPtr.ToPointer(), ManagedHandle.ToIntPtr(exception, GCHandleType.Weak));
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
return returnValue;
|
||||
@@ -721,7 +763,7 @@ namespace FlaxEngine.Interop
|
||||
|
||||
for (int i = 0; i < numParams; i++)
|
||||
{
|
||||
IntPtr nativePtr = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i));
|
||||
IntPtr nativePtr = Unsafe.Read<IntPtr>((IntPtr.Add(paramPtr, sizeof(IntPtr) * i)).ToPointer());
|
||||
methodParameters[i] = MarshalToManaged(nativePtr, methodHolder.parameterTypes[i]);
|
||||
}
|
||||
|
||||
@@ -737,7 +779,7 @@ namespace FlaxEngine.Interop
|
||||
realException = exception.InnerException;
|
||||
|
||||
if (exceptionPtr != IntPtr.Zero)
|
||||
Marshal.WriteIntPtr(exceptionPtr, ManagedHandle.ToIntPtr(realException, GCHandleType.Weak));
|
||||
Unsafe.Write<IntPtr>(exceptionPtr.ToPointer(), ManagedHandle.ToIntPtr(realException, GCHandleType.Weak));
|
||||
else
|
||||
throw realException;
|
||||
return IntPtr.Zero;
|
||||
@@ -749,7 +791,7 @@ namespace FlaxEngine.Interop
|
||||
Type parameterType = methodHolder.parameterTypes[i];
|
||||
if (parameterType.IsByRef)
|
||||
{
|
||||
IntPtr nativePtr = Marshal.ReadIntPtr(IntPtr.Add(paramPtr, sizeof(IntPtr) * i));
|
||||
IntPtr nativePtr = Unsafe.Read<IntPtr>((IntPtr.Add(paramPtr, sizeof(IntPtr) * i)).ToPointer());
|
||||
MarshalToNative(methodParameters[i], nativePtr, parameterType.GetElementType());
|
||||
}
|
||||
}
|
||||
@@ -803,7 +845,7 @@ namespace FlaxEngine.Interop
|
||||
internal static int FieldGetOffset(ManagedHandle fieldHandle)
|
||||
{
|
||||
FieldHolder field = Unsafe.As<FieldHolder>(fieldHandle.Target);
|
||||
return (int)Marshal.OffsetOf(field.field.DeclaringType, field.field.Name);
|
||||
return field.fieldOffset;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -811,7 +853,40 @@ namespace FlaxEngine.Interop
|
||||
{
|
||||
object fieldOwner = fieldOwnerHandle.Target;
|
||||
FieldHolder field = Unsafe.As<FieldHolder>(fieldHandle.Target);
|
||||
field.toNativeMarshaller(field.field, fieldOwner, valuePtr, out int fieldOffset);
|
||||
field.toNativeMarshaller(field.fieldOffset, fieldOwner, valuePtr, out int fieldSize);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void FieldGetValueReference(ManagedHandle fieldOwnerHandle, ManagedHandle fieldHandle, IntPtr valuePtr)
|
||||
{
|
||||
object fieldOwner = fieldOwnerHandle.Target;
|
||||
FieldHolder field = Unsafe.As<FieldHolder>(fieldHandle.Target);
|
||||
if (fieldOwner.GetType().IsValueType)
|
||||
{
|
||||
ref IntPtr fieldRef = ref FieldHelper.GetValueTypeFieldReference<object, IntPtr>(field.fieldOffset, ref fieldOwner);
|
||||
Unsafe.Write<IntPtr>(valuePtr.ToPointer(), fieldRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref IntPtr fieldRef = ref FieldHelper.GetReferenceTypeFieldReference<object, IntPtr>(field.fieldOffset, ref fieldOwner);
|
||||
Unsafe.Write<IntPtr>(valuePtr.ToPointer(), fieldRef);
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static void FieldGetValueReferenceWithOffset(ManagedHandle fieldOwnerHandle, int fieldOffset, IntPtr valuePtr)
|
||||
{
|
||||
object fieldOwner = fieldOwnerHandle.Target;
|
||||
if (fieldOwner.GetType().IsValueType)
|
||||
{
|
||||
ref IntPtr fieldRef = ref FieldHelper.GetValueTypeFieldReference<object, IntPtr>(fieldOffset, ref fieldOwner);
|
||||
Unsafe.Write<IntPtr>(valuePtr.ToPointer(), fieldRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref IntPtr fieldRef = ref FieldHelper.GetReferenceTypeFieldReference<object, IntPtr>(fieldOffset, ref fieldOwner);
|
||||
Unsafe.Write<IntPtr>(valuePtr.ToPointer(), fieldRef);
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -839,7 +914,15 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle LoadAssemblyImage(IntPtr assemblyPathPtr, IntPtr* assemblyName, IntPtr* assemblyFullName)
|
||||
internal static void GetAssemblyName(ManagedHandle assemblyHandle, IntPtr* assemblyName, IntPtr* assemblyFullName)
|
||||
{
|
||||
Assembly assembly = Unsafe.As<Assembly>(assemblyHandle.Target);
|
||||
*assemblyName = NativeAllocStringAnsi(assembly.GetName().Name);
|
||||
*assemblyFullName = NativeAllocStringAnsi(assembly.FullName);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle LoadAssemblyImage(IntPtr assemblyPathPtr)
|
||||
{
|
||||
if (!firstAssemblyLoaded)
|
||||
{
|
||||
@@ -847,8 +930,6 @@ namespace FlaxEngine.Interop
|
||||
firstAssemblyLoaded = true;
|
||||
|
||||
Assembly flaxEngineAssembly = AssemblyLoadContext.Default.Assemblies.First(x => x.GetName().Name == "FlaxEngine.CSharp");
|
||||
*assemblyName = NativeAllocStringAnsi(flaxEngineAssembly.GetName().Name);
|
||||
*assemblyFullName = NativeAllocStringAnsi(flaxEngineAssembly.FullName);
|
||||
return GetAssemblyHandle(flaxEngineAssembly);
|
||||
}
|
||||
try
|
||||
@@ -882,8 +963,6 @@ namespace FlaxEngine.Interop
|
||||
// Assemblies loaded via streams have no Location: https://github.com/dotnet/runtime/issues/12822
|
||||
AssemblyLocations.Add(assembly.FullName, assemblyPath);
|
||||
|
||||
*assemblyName = NativeAllocStringAnsi(assembly.GetName().Name);
|
||||
*assemblyFullName = NativeAllocStringAnsi(assembly.FullName);
|
||||
return GetAssemblyHandle(assembly);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -894,15 +973,12 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetAssemblyByName(IntPtr namePtr, IntPtr* assemblyName, IntPtr* assemblyFullName)
|
||||
internal static ManagedHandle GetAssemblyByName(IntPtr namePtr)
|
||||
{
|
||||
string name = Marshal.PtrToStringAnsi(namePtr);
|
||||
Assembly assembly = Utils.GetAssemblies().FirstOrDefault(x => x.GetName().Name == name);
|
||||
if (assembly == null)
|
||||
return new ManagedHandle();
|
||||
|
||||
*assemblyName = NativeAllocStringAnsi(assembly.GetName().Name);
|
||||
*assemblyFullName = NativeAllocStringAnsi(assembly.FullName);
|
||||
return GetAssemblyHandle(assembly);
|
||||
}
|
||||
|
||||
@@ -941,9 +1017,9 @@ namespace FlaxEngine.Interop
|
||||
|
||||
// Release all references in collectible ALC
|
||||
cachedDelegatesCollectible.Clear();
|
||||
foreach (var pair in typeHandleCacheCollectible)
|
||||
pair.Value.Free();
|
||||
typeHandleCacheCollectible.Clear();
|
||||
foreach (var pair in managedTypesCollectible)
|
||||
pair.Value.handle.Free();
|
||||
managedTypesCollectible.Clear();
|
||||
foreach (var handle in methodHandlesCollectible)
|
||||
handle.Free();
|
||||
methodHandlesCollectible.Clear();
|
||||
@@ -973,7 +1049,7 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static int NativeSizeOf(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type nativeType = GetInternalType(type) ?? type;
|
||||
if (nativeType == typeof(Version))
|
||||
nativeType = typeof(NativeVersion);
|
||||
@@ -991,8 +1067,8 @@ namespace FlaxEngine.Interop
|
||||
if (typeHandle == otherTypeHandle)
|
||||
return 1;
|
||||
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type otherType = Unsafe.As<Type>(otherTypeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type otherType = Unsafe.As<TypeHolder>(otherTypeHandle.Target);
|
||||
|
||||
if (type == otherType)
|
||||
return 1;
|
||||
@@ -1009,37 +1085,39 @@ namespace FlaxEngine.Interop
|
||||
[UnmanagedCallersOnly]
|
||||
internal static byte TypeIsAssignableFrom(ManagedHandle typeHandle, ManagedHandle otherTypeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type otherType = Unsafe.As<Type>(otherTypeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
Type otherType = Unsafe.As<TypeHolder>(otherTypeHandle.Target);
|
||||
return (byte)(type.IsAssignableFrom(otherType) ? 1 : 0);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static byte TypeIsValueType(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
return (byte)(type.IsValueType ? 1 : 0);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static byte TypeIsEnum(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
return (byte)(type.IsEnum ? 1 : 0);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetClassParent(ManagedHandle typeHandle)
|
||||
internal static IntPtr GetClassParent(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
return GetTypeGCHandle(type.BaseType);
|
||||
TypeHolder typeHolder = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
TypeHolder baseTypeHolder = GetTypeHolder(typeHolder.type.BaseType);
|
||||
return baseTypeHolder.managedClassPointer;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetElementClass(ManagedHandle typeHandle)
|
||||
internal static IntPtr GetElementClass(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
return GetTypeGCHandle(type.GetElementType());
|
||||
TypeHolder typeHolder = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
TypeHolder elementTypeHolder = GetTypeHolder(typeHolder.type.GetElementType());
|
||||
return elementTypeHolder.managedClassPointer;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
@@ -1130,32 +1208,35 @@ namespace FlaxEngine.Interop
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static ManagedHandle GetTypeClass(ManagedHandle typeHandle)
|
||||
internal static IntPtr GetTypeClass(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
if (type.IsByRef)
|
||||
type = type.GetElementType(); // Drop reference type (&) to get actual value type
|
||||
return GetTypeGCHandle(type);
|
||||
TypeHolder typeHolder = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
if (typeHolder.type.IsByRef)
|
||||
{
|
||||
// Drop reference type (&) to get actual value type
|
||||
return GetTypeHolder(typeHolder.type.GetElementType()).managedClassPointer;
|
||||
}
|
||||
return typeHolder.managedClassPointer;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static bool GetTypeIsPointer(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
return type.IsPointer;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static bool GetTypeIsReference(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
return type.IsByRef;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly]
|
||||
internal static uint GetTypeMTypesEnum(ManagedHandle typeHandle)
|
||||
{
|
||||
Type type = Unsafe.As<Type>(typeHandle.Target);
|
||||
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||
if (type.IsByRef)
|
||||
type = type.GetElementType(); // Drop reference type (&) to get actual value type
|
||||
MTypes monoType;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user