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));
        }
示例#2
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 }));
        }
示例#3
0
        public Il2CppObjectBase(IntPtr pointer)
        {
            if (pointer == IntPtr.Zero)
            {
                throw new NullReferenceException();
            }

            myGcHandle = IL2CPP.il2cpp_gchandle_new(pointer, false);
        }
        public Il2CppObjectBase(IntPtr pointer)
        {
            if (pointer == IntPtr.Zero)
            {
                throw new NullReferenceException();
            }

            myGcHandle = RuntimeSpecificsStore.ShouldUseWeakRefs(IL2CPP.il2cpp_object_get_class(pointer))
                ? IL2CPP.il2cpp_gchandle_new_weakref(pointer, false)
                : IL2CPP.il2cpp_gchandle_new(pointer, false);
        }
        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);
        }
示例#6
0
        private static IntPtr AllocateArray(long size)
        {
            if (size < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(size), "Array size must not be negative");
            }

            var elementTypeClassPointer = Il2CppClassPointerStore <string> .NativeClassPtr;

            if (elementTypeClassPointer == IntPtr.Zero)
            {
                throw new ArgumentException("String class pointer is missing, something is very wrong");
            }
            return(IL2CPP.il2cpp_array_new(elementTypeClassPointer, (ulong)size));
        }
        private static IntPtr AllocateArray(long size)
        {
            if (size < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(size), "Array size must not be negative");
            }

            var elementTypeClassPointer = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (elementTypeClassPointer == IntPtr.Zero)
            {
                throw new ArgumentException($"{nameof(Il2CppStructArray<T>)} requires an Il2Cpp reference type, which {typeof(T)} isn't");
            }
            return(IL2CPP.il2cpp_array_new(elementTypeClassPointer, (ulong)size));
        }
        private static unsafe string BuildMessage(IntPtr exception)
        {
            ourMessageBytes ??= new byte[65536];

            fixed(byte *message = ourMessageBytes)
            IL2CPP.il2cpp_format_exception(exception, message, ourMessageBytes.Length);

            string builtMessage = Encoding.UTF8.GetString(ourMessageBytes, 0, Array.IndexOf(ourMessageBytes, (byte)0));

            fixed(byte *message = ourMessageBytes)
            IL2CPP.il2cpp_format_stack_trace(exception, message, ourMessageBytes.Length);

            builtMessage +=
                "\n" + Encoding.UTF8.GetString(ourMessageBytes, 0, Array.IndexOf(ourMessageBytes, (byte)0));
            return(builtMessage);
        }
        static Il2CppReferenceArray()
        {
            ourElementTypeSize = IntPtr.Size;
            var nativeClassPtr = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (nativeClassPtr == IntPtr.Zero)
            {
                return;
            }
            uint align = 0;

            if (IL2CPP.il2cpp_class_is_valuetype(nativeClassPtr))
            {
                ourElementIsValueType = true;
                ourElementTypeSize    = IL2CPP.il2cpp_class_value_size(nativeClassPtr, ref align);
            }
        }
        internal void CreateGCHandle(IntPtr objHdl)
        {
            if (objHdl == IntPtr.Zero)
            {
                throw new NullReferenceException();
            }

            // This object already wraps an Il2Cpp object, skip the pointer and let it be GC'd
            if (isWrapped)
            {
                return;
            }

            myGcHandle = RuntimeSpecificsStore.ShouldUseWeakRefs(IL2CPP.il2cpp_object_get_class(objHdl))
                ? IL2CPP.il2cpp_gchandle_new_weakref(objHdl, false)
                : IL2CPP.il2cpp_gchandle_new(objHdl, false);
        }
        public T Unbox <T>() where T : unmanaged
        {
            var nestedTypeClassPointer = Il2CppClassPointerStore <T> .NativeClassPtr;

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

            var ownClass = IL2CPP.il2cpp_object_get_class(Pointer);

            if (!IL2CPP.il2cpp_class_is_assignable_from(nestedTypeClassPointer, ownClass))
            {
                throw new InvalidCastException($"Can't cast object of type {Marshal.PtrToStringAnsi(IL2CPP.il2cpp_class_get_name(IL2CPP.il2cpp_object_get_class(Pointer)))} to type {typeof(T)}");
            }

            return(Marshal.PtrToStructure <T>(IL2CPP.il2cpp_object_unbox(Pointer)));
        }
        protected static void StaticCtorBody(Type ownType)
        {
            var nativeClassPtr = Il2CppClassPointerStore <T> .NativeClassPtr;

            if (nativeClassPtr == IntPtr.Zero)
            {
                return;
            }

            var targetClassType = IL2CPP.il2cpp_array_class_get(nativeClassPtr, 1);

            if (targetClassType == IntPtr.Zero)
            {
                return;
            }

            Il2CppClassPointerStore.SetNativeClassPointer(ownType, targetClassType);
            Il2CppClassPointerStore.SetNativeClassPointer(typeof(Il2CppArrayBase <T>), targetClassType);
            Il2CppClassPointerStore <Il2CppArrayBase <T> > .CreatedTypeRedirect = ownType;
        }
示例#13
0
        private static unsafe void StoreValue(IntPtr targetPointer, IntPtr valuePointer)
        {
            if (ourElementIsValueType)
            {
                if (valuePointer == IntPtr.Zero)
                {
                    throw new NullReferenceException();
                }

                var valueRawPointer  = (byte *)IL2CPP.il2cpp_object_unbox(valuePointer);
                var targetRawPointer = (byte *)targetPointer;
                for (var i = 0; i < ourElementTypeSize; i++)
                {
                    targetRawPointer[i] = valueRawPointer[i];
                }
            }
            else
            {
                *(IntPtr *)targetPointer = valuePointer;
            }
        }
        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);
            }

            return((T)ourCachedInstanceCtor.Invoke(new object[] { referencePointer }));
        }
示例#15
0
 public override unsafe string this[int index]
 {
     get
     {
         if (index < 0 || index >= Length)
         {
             throw new ArgumentOutOfRangeException(nameof(index), "Array index may not be negative or above length of the array");
         }
         var arrayStartPointer = IntPtr.Add(Pointer, 4 * IntPtr.Size);
         var elementPointer    = IntPtr.Add(arrayStartPointer, index * IntPtr.Size);
         return(IL2CPP.Il2CppStringToManaged(*(IntPtr *)elementPointer));
     }
     set
     {
         if (index < 0 || index >= Length)
         {
             throw new ArgumentOutOfRangeException(nameof(index), "Array index may not be negative or above length of the array");
         }
         var arrayStartPointer = IntPtr.Add(Pointer, 4 * IntPtr.Size);
         var elementPointer    = IntPtr.Add(arrayStartPointer, index * IntPtr.Size);
         *(IntPtr *)elementPointer = IL2CPP.ManagedStringToIl2Cpp(value);
     }
 }
 public T Cast <T>() where T : Il2CppObjectBase
 {
     return(TryCast <T>() ?? throw new InvalidCastException($"Can't cast object of type {Marshal.PtrToStringAnsi(IL2CPP.il2cpp_class_get_name(IL2CPP.il2cpp_object_get_class(Pointer)))} to type {typeof(T)}"));
 }