Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remember injected types and reuse in GetIl2CppTypeFullName #103

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions Il2CppInterop.Runtime/Injection/ClassInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 8 additions & 5 deletions Il2CppInterop.Runtime/Injection/InjectorHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -139,6 +141,7 @@ internal static IntPtr GetIl2CppMethodPointer(MethodBase proxyMethod)
internal static readonly ConcurrentDictionary<long, IntPtr> s_InjectedClasses = new();
/// <summary> (namespace, class, image) : class </summary>
internal static readonly Dictionary<(string _namespace, string _class, IntPtr imagePtr), IntPtr> s_ClassNameLookup = new();
internal static readonly Dictionary<IntPtr, Type> s_TypeLookup = new();

#region Class::Init
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
Expand Down
Loading