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)); }
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 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); }
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; }
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 })); }
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)}")); }