2020-10-16 19:40:01 +11:00
|
|
|
|
#if CPP
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2020-10-18 21:41:04 +11:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-10-28 06:39:26 +11:00
|
|
|
|
using System.Runtime.InteropServices;
|
2020-10-16 19:40:01 +11:00
|
|
|
|
|
2021-03-18 17:17:29 +11:00
|
|
|
|
namespace UnityExplorer.Core.Runtime.Il2Cpp
|
2020-10-16 19:40:01 +11:00
|
|
|
|
{
|
2020-10-18 21:41:04 +11:00
|
|
|
|
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
|
2021-03-18 17:17:29 +11:00
|
|
|
|
public static class ICallManager
|
2020-10-16 19:40:01 +11:00
|
|
|
|
{
|
|
|
|
|
private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();
|
|
|
|
|
|
2021-03-12 18:41:57 +11:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Helper to get and cache an iCall by providing the signature (eg. "UnityEngine.Resources::FindObjectsOfTypeAll").
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="T">The Type of Delegate to provide for the iCall.</typeparam>
|
|
|
|
|
/// <param name="signature">The signature of the iCall you want to get.</param>
|
|
|
|
|
/// <returns>The <typeparamref name="T"/> delegate if successful.</returns>
|
|
|
|
|
/// <exception cref="MissingMethodException">If the iCall could not be found.</exception>
|
|
|
|
|
public static T GetICall<T>(string signature) where T : Delegate
|
2020-10-16 19:40:01 +11:00
|
|
|
|
{
|
2021-03-12 18:41:57 +11:00
|
|
|
|
if (iCallCache.ContainsKey(signature))
|
|
|
|
|
return (T)iCallCache[signature];
|
2020-10-16 19:40:01 +11:00
|
|
|
|
|
2021-03-12 18:41:57 +11:00
|
|
|
|
IntPtr ptr = il2cpp_resolve_icall(signature);
|
2020-10-16 19:40:01 +11:00
|
|
|
|
|
|
|
|
|
if (ptr == IntPtr.Zero)
|
|
|
|
|
{
|
2021-03-12 18:41:57 +11:00
|
|
|
|
throw new MissingMethodException($"Could not resolve internal call by name '{signature}'!");
|
2020-10-16 19:40:01 +11:00
|
|
|
|
}
|
|
|
|
|
|
2020-10-28 06:39:26 +11:00
|
|
|
|
Delegate iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
|
2021-03-12 18:41:57 +11:00
|
|
|
|
iCallCache.Add(signature, iCall);
|
2020-10-16 19:40:01 +11:00
|
|
|
|
|
|
|
|
|
return (T)iCall;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
|
|
|
|
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|