diff --git a/Il2CppInterop.Runtime/Injection/ClassInjector.cs b/Il2CppInterop.Runtime/Injection/ClassInjector.cs index e287a086..b54ed9cb 100644 --- a/Il2CppInterop.Runtime/Injection/ClassInjector.cs +++ b/Il2CppInterop.Runtime/Injection/ClassInjector.cs @@ -522,7 +522,8 @@ INativeMethodInfoStruct HandleAbstractMethod(int position) RuntimeSpecificsStore.SetClassInfo(classPointer.Pointer, true); Il2CppClassPointerStore.SetNativeClassPointer(type, classPointer.Pointer); - InjectorHelpers.AddTypeToLookup(type, classPointer.Pointer); + var classTypePtr = IL2CPP.il2cpp_class_get_type(classPointer.Pointer); + InjectorHelpers.AddTypeToLookup(type, classTypePtr); if (options.LogSuccess) Logger.Instance.LogInformation("Registered mono type {Type} in il2cpp domain", type); @@ -533,7 +534,7 @@ private static bool IsTypeSupported(Type type) if (type.IsValueType || type == typeof(string) || type.IsGenericParameter) return true; - if (type.IsByRef) return IsTypeSupported(type.GetElementType()); + if (type.IsByRef || type.IsPointer) return IsTypeSupported(type.GetElementType()); return typeof(Il2CppObjectBase).IsAssignableFrom(type); } @@ -654,7 +655,7 @@ private static bool IsMethodEligible(MethodInfo method) var parameterType = parameterInfo.ParameterType; if (!parameterType.IsGenericParameter) { - if (parameterType.IsByRef) + if (parameterType.IsByRef || parameterType.IsPointer) { var elementType = parameterType.GetElementType(); if (!elementType.IsGenericParameter) @@ -1082,7 +1083,7 @@ private static Type RewriteType(Type type) if (type.IsValueType && !type.IsEnum) return type; - if (type == typeof(string)) + if (type == typeof(string) || type == typeof(void*)) return type; if (type.IsArray) @@ -1147,10 +1148,16 @@ private static string GetIl2CppTypeFullName(Il2CppTypeStruct* typePointer) internal static Type SystemTypeFromIl2CppType(Il2CppTypeStruct* typePointer) { + INativeTypeStruct wrappedType = UnityVersionHandler.Wrap(typePointer); + + if (InjectorHelpers.TryGetType((IntPtr)wrappedType.TypePointer, out var type)) + { + return RewriteType(type); + } + var fullName = GetIl2CppTypeFullName(typePointer); - var type = Type.GetType(fullName) ?? throw new NullReferenceException($"Couldn't find System.Type for Il2Cpp type: {fullName}"); + type = Type.GetType(fullName) ?? throw new NullReferenceException($"Couldn't find System.Type for Il2Cpp type: {fullName}"); - INativeTypeStruct wrappedType = UnityVersionHandler.Wrap(typePointer); if (wrappedType.Type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) { Il2CppGenericClass* genericClass = (Il2CppGenericClass*)wrappedType.Data; diff --git a/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs b/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs index b1729e42..3ae136ed 100644 --- a/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs +++ b/Il2CppInterop.Runtime/Injection/InjectorHelpers.cs @@ -8,16 +8,11 @@ using System.Runtime.InteropServices; using System.Threading; using Il2CppInterop.Common; -using Il2CppInterop.Common.Extensions; -using Il2CppInterop.Common.XrefScans; using Il2CppInterop.Runtime.Injection.Hooks; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Assembly; -using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class; -using Il2CppInterop.Runtime.Runtime.VersionSpecific.FieldInfo; using Il2CppInterop.Runtime.Runtime.VersionSpecific.Image; using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo; -using Il2CppInterop.Runtime.Startup; using Microsoft.Extensions.Logging; namespace Il2CppInterop.Runtime.Injection @@ -100,6 +95,13 @@ internal static void AddTypeToLookup(Type type, IntPtr typePointer) { s_ClassNameLookup.Add((namespaze, klass, image), typePointer); } + + s_TypeLookup[typePointer] = type; + } + + internal static bool TryGetType(IntPtr typePointer, out Type type) + { + return s_TypeLookup.TryGetValue(typePointer, out type); } internal static IntPtr GetIl2CppExport(string name) @@ -139,6 +141,7 @@ internal static IntPtr GetIl2CppMethodPointer(MethodBase proxyMethod) internal static readonly ConcurrentDictionary s_InjectedClasses = new(); /// (namespace, class, image) : class internal static readonly Dictionary<(string _namespace, string _class, IntPtr imagePtr), IntPtr> s_ClassNameLookup = new(); + internal static readonly Dictionary s_TypeLookup = new(); #region Class::Init [UnmanagedFunctionPointer(CallingConvention.Cdecl)]