老样子,小姐姐镇楼
我们继续来一起看下ILRuntime的第二个案例———Invocation:方法的调用。
这是这一系列文章的总目录链接
有疑问的可以先看下之前的文章。
Unity热更新 ILRuntime 从零开始 方法调用 Invocation(三)
🎁ILRuntime工程添加脚本 方法
在ILRuntime工程的目录下,会找到InstanceClass.cs这个脚本,里面有几个方法,便于在Unity里面调用
public static void StaticFunTest()
{
UnityEngine.Debug.Log("!!! InstanceClass.StaticFunTest()");
//UnityEngine.Debug.Log("Hello World!");
}
public static void StaticFunTest2(int a)
{
UnityEngine.Debug.Log("!!! InstanceClass.StaticFunTest2(), a=" + a);
}
public static void GenericMethod<T>(T a)
{
UnityEngine.Debug.Log("!!! InstanceClass.GenericMethod(), a=" + a);
}
public void RefOutMethod(int addition, out List<int> lst, ref int val)
{
val = val + addition + id;
lst = new List<int>();
lst.Add(id);
}
🎁一、调用无参数静态方法
//调用无参数静态方法,appdomain.Invoke("类名", "方法名", 对象引用, 参数列表);
appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest", null, null);
🎁二、调用带参数的静态方法
//调用带参数的静态方法,appdomain.Invoke("类名", "方法名", 对象引用, 参数列表);
appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest2", null, 123);
🎁三、通过IMethod调用方法
//预先获得IMethod,可以减低每次调用查找方法耗用的时间
IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
//根据方法名称和参数个数获取方法
IMethod method = type.GetMethod("StaticFunTest2", 1);
appdomain.Invoke(method, null, 123);
这里解释下:IType
和IMethod
都是ILRuntime自己的用于反射的辅助类,跟Unity 的反射用法也是一样的,这里是通过反射获取,来调用方法的。
🎁四、通过无GC Alloc方式调用方法
🌲1.指定参数类型获取IMethod
using (var ctx = appdomain.BeginInvoke(method))
{
ctx.PushInteger(123);
ctx.Invoke();
}
Debug.Log("指定参数类型来获得IMethod");
IType intType = appdomain.GetType(typeof(int));
//参数类型列表
List<IType> paramList = new List<ILRuntime.CLR.TypeSystem.IType>();
paramList.Add(intType);
//根据方法名称和参数类型列表获取方法
method = type.GetMethod("StaticFunTest2", paramList, null);
appdomain.Invoke(method, null, 456);
🌲2.调用成员方法
首先我们来实例化类
object obj = appdomain.Instantiate("HotFix_Project.InstanceClass", new object[] { 233 });
//第二种方式,通过反射实例化
object obj2 = ((ILType)type).Instantiate();
然后通过反射调用成员方法
method = type.GetMethod("get_ID", 0);
using (var ctx = appdomain.BeginInvoke(method))
{
ctx.PushObject(obj);
ctx.Invoke();
int id = ctx.ReadInteger();
Debug.Log("!! HotFix_Project.InstanceClass.ID = " + id);
}
using (var ctx = appdomain.BeginInvoke(method))
{
ctx.PushObject(obj2);
ctx.Invoke();
int id = ctx.ReadInteger();
Debug.Log("!! HotFix_Project.InstanceClass.ID = " + id);
}
🌲3.调用泛型方法
🌸(1)直接通过appdomain.InvokeGenericMethod
来调用
IType stringType = appdomain.GetType(typeof(string));
IType[] genericArguments = new IType[] { stringType };
appdomain.InvokeGenericMethod("HotFix_Project.InstanceClass", "GenericMethod", genericArguments, null, "TestString");
🌸(2)通过获取泛型方法的IMethod来调用
paramList.Clear();
paramList.Add(intType);
genericArguments = new IType[] { intType };
method = type.GetMethod("GenericMethod", paramList, genericArguments);
appdomain.Invoke(method, null, 33333);
🌲4.调用带Ref/Out参数的方法
method = type.GetMethod("RefOutMethod", 3);
int initialVal = 500;
using(var ctx = appdomain.BeginInvoke(method))
{
//第一个ref/out参数初始值
ctx.PushObject(null);
//第二个ref/out参数初始值
ctx.PushInteger(initialVal);
//压入this
ctx.PushObject(obj);
//压入参数1:addition
ctx.PushInteger(100);
//压入参数2: lst,由于是ref/out,需要压引用,这里是引用0号位,也就是第一个PushObject的位置
ctx.PushReference(0);
//压入参数3,val,同ref/out
ctx.PushReference(1);
ctx.Invoke();
//读取0号位的值
List<int> lst = ctx.ReadObject<List<int>>(0);
initialVal = ctx.ReadInteger(1);
Debug.Log(string.Format("lst[0]={0}, initialVal={1}", lst[0], initialVal));
}
总结
欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。
如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~
声明:本博文章若非特殊注明皆为原创原文链接
https://blog.csdn.net/Wrinkle2017/article/details/120490147
————————————————————————————————
💢💢版权声明
版权声明:本博客为非营利性个人原创
所刊登的所有作品的著作权均为本人所拥有
本人保留所有法定权利,违者必究!
对于需要复制、转载、链接和传播博客文章或内容的
请及时和本博主进行联系
对于经本博主明确授权和许可使用文章及内容的
使用时请注明文章或内容出处并注明网址
转载请附上原文出处链接及本声明