Unity热更新 ILRuntime 从零开始 方法调用 Invocation(三)

老样子,小姐姐镇楼
请添加图片描述
我们继续来一起看下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);

这里解释下:ITypeIMethod都是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
————————————————————————————————

💢💢版权声明

版权声明:本博客为非营利性个人原创
所刊登的所有作品的著作权均为本人所拥有
本人保留所有法定权利,违者必究!
对于需要复制、转载、链接和传播博客文章或内容的
请及时和本博主进行联系
对于经本博主明确授权和许可使用文章及内容的
使用时请注明文章或内容出处并注明网址
转载请附上原文出处链接及本声明

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值