Пример #1
0
        private static unsafe T WrapElement(IntPtr memberPointer)
        {
            if (ourCachedInstanceCtor == null)
            {
                ourCachedInstanceCtor = typeof(T).GetConstructor(new[] { typeof(IntPtr) });
            }

            if (ourElementIsValueType)
            {
                return((T)ourCachedInstanceCtor.Invoke(new object[]
                                                       { IL2CPP.il2cpp_value_box(Il2CppClassPointerStore <T> .NativeClassPtr, memberPointer) }));
            }

            var referencePointer = *(IntPtr *)memberPointer;

            if (referencePointer == IntPtr.Zero)
            {
                return(null);
            }

            if (typeof(Il2CppObjectBase).IsAssignableFrom(typeof(T)))
            {
                var typePtr           = Il2CppClassPointerStore <T> .NativeClassPtr;
                var referenceClassPtr = IL2CPP.il2cpp_object_get_class(referencePointer);
                if (RuntimeSpecificsStore.IsInjected(typePtr) && IL2CPP.il2cpp_class_is_assignable_from(typePtr, referenceClassPtr))
                {
                    return(ClassInjectorBase.GetMonoObjectFromIl2CppPointer(referencePointer) as T);
                }
            }

            return((T)ourCachedInstanceCtor.Invoke(new object[] { referencePointer }));
        }
        public T TryCast <T>() where T : Il2CppObjectBase
        {
            var nestedTypeClassPointer = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (nestedTypeClassPointer == IntPtr.Zero)
            {
                throw new ArgumentException($"{typeof(T)} is not al Il2Cpp reference type");
            }

            // todo: support arrays

            var ownClass = IL2CPP.il2cpp_object_get_class(Pointer);

            if (!IL2CPP.il2cpp_class_is_assignable_from(nestedTypeClassPointer, ownClass))
            {
                return(null);
            }

            if (RuntimeSpecificsStore.IsInjected(ownClass))
            {
                return(ClassInjectorBase.GetMonoObjectFromIl2CppPointer(Pointer) as T);
            }

            return((T)Activator.CreateInstance(typeof(T), Pointer));
        }
Пример #3
0
        /// <summary>
        /// Version of TryCast without the generic restriction
        /// </summary>
        private static bool TryCast <T>(Il2CppObjectBase obj, out T t)
        {
            t = default;
            var nativeClassPtr = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (nativeClassPtr == IntPtr.Zero)
            {
                MelonLogger.Warning($"{typeof(T)} is not an Il2Cpp reference type");
                return(false);
            }

            var num = IL2CPP.il2cpp_object_get_class(obj.Pointer);

            if (!IL2CPP.il2cpp_class_is_assignable_from(nativeClassPtr, num))
            {
                MelonLogger.Warning($"{obj.GetType()} is not a {typeof(T)}");
                return(false);
            }

            if (RuntimeSpecificsStore.IsInjected(num))
            {
                t = (T)ClassInjectorBase.GetMonoObjectFromIl2CppPointer(obj.Pointer);
                return(true);
            }

            var type = Il2CppClassPointerStore <T> .CreatedTypeRedirect;

            if ((object)type == null)
            {
                type = typeof(T);
            }

            t = (T)Activator.CreateInstance(type, obj.Pointer);
            return(true);
        }
        public T TryCast <T>() where T : Il2CppObjectBase
        {
            var nestedTypeClassPointer = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (nestedTypeClassPointer == IntPtr.Zero)
            {
                throw new ArgumentException($"{typeof(T)} is not an Il2Cpp reference type");
            }

            var ownClass = IL2CPP.il2cpp_object_get_class(Pointer);

            if (!IL2CPP.il2cpp_class_is_assignable_from(nestedTypeClassPointer, ownClass))
            {
                return(null);
            }

            if (RuntimeSpecificsStore.IsInjected(ownClass))
            {
                var monoObject = ClassInjectorBase.GetMonoObjectFromIl2CppPointer(Pointer) as T;
                if (monoObject != null)
                {
                    return(monoObject);
                }
            }

            var type = Il2CppClassPointerStore <T> .CreatedTypeRedirect ?? typeof(T);

            // Base case: Il2Cpp constructor => call it directly
            if (type.GetConstructor(new[] { typeof(IntPtr) }) != null)
            {
                return((T)Activator.CreateInstance(type, Pointer));
            }

            // Special case: We have a parameterless constructor
            // However, it could be be user-made or implicit
            // In that case we set the GCHandle and then call the ctor and let GC destroy any objects created by DerivedConstructorPointer
            var obj = (T)FormatterServices.GetUninitializedObject(type);

            obj.CreateGCHandle(Pointer);
            obj.isWrapped = true;
            var ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
                                           Type.EmptyTypes, Array.Empty <ParameterModifier>());

            if (ctor != null)
            {
                ctor.Invoke(obj, null);
            }
            return(obj);
        }
Пример #5
0
        public static bool Is <T>(this Il2CppObjectBase obj)
        {
            var nestedTypeClassPointer = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (nestedTypeClassPointer == IntPtr.Zero)
            {
                throw new ArgumentException($"{typeof(T)} is not an Il2Cpp reference type");
            }

            var ownClass = IL2CPP.il2cpp_object_get_class(obj.Pointer);

            if (!IL2CPP.il2cpp_class_is_assignable_from(nestedTypeClassPointer, ownClass))
            {
                return(false);
            }

            if (RuntimeSpecificsStore.IsInjected(ownClass))
            {
                return(ClassInjectorBase.GetMonoObjectFromIl2CppPointer(obj.Pointer) is T);
            }

            return(true);
        }
        public static void Finalize(IntPtr ptr)
        {
            var gcHandle = ClassInjectorBase.GetGcHandlePtrFromIl2CppObject(ptr);

            GCHandle.FromIntPtr(gcHandle).Free();
        }