#if CPP using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace UnityExplorer.Core.Runtime.Il2Cpp { [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")] public static class ICallManager { private static readonly Dictionary iCallCache = new Dictionary(); /// /// Helper to get and cache an iCall by providing the signature (eg. "UnityEngine.Resources::FindObjectsOfTypeAll"). /// /// The Type of Delegate to provide for the iCall. /// The signature of the iCall you want to get. /// The delegate if successful. /// If the iCall could not be found. public static T GetICall(string signature) where T : Delegate { if (iCallCache.ContainsKey(signature)) return (T)iCallCache[signature]; IntPtr ptr = il2cpp_resolve_icall(signature); if (ptr == IntPtr.Zero) { throw new MissingMethodException($"Could not resolve internal call by name '{signature}'!"); } Delegate iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)); iCallCache.Add(signature, iCall); return (T)iCall; } [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name); } } #endif