ILRuntime学习笔记(二)——主工程与热更工程的相互调用

主工程与热更工程的相互调用

一、在主工程调用热更的方法

1.使用AppDomian,直接使用字符串名字调用

1.1 调用无参数静态方法
appdomain.Invoke(“类名”, “方法名”, 对象引用[如果是静态方法为null,非静态方法传object对象], 参数列表);
主工程:

appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest", null, null);

热更工程:

        public static void StaticFunTest()
        {
    
    
            UnityEngine.Debug.Log("!!! InstanceClass.StaticFunTest()");
        }

1.2 调用无参数方法

主工程:

        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass", new object[] {
    
     233 });
        appdomain.Invoke("HotFix_Project.InstanceClass", "FunTest", obj, null);

热更工程:

        public void FunTest()
        {
    
    
            UnityEngine.Debug.Log("!!! InstanceClass.FunTest()");
        }

1.3调用有参数静态方法
主工程:

        appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest2", null, 123);

热更工程:

        public static void StaticFunTest2(int a)
        {
    
    
            UnityEngine.Debug.Log("!!! InstanceClass.StaticFunTest2(), a=" + a);
        }

1.4 调用有参数方法
主工程:


        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass");
        appdomain.Invoke("HotFix_Project.InstanceClass", "FunTest2", obj, 22);

热更工程:

        public void FunTest2(int a)
        {
    
    
            UnityEngine.Debug.Log("!!! InstanceClass.FunTest2(),a=" + a);
        }

1.5 实例化热更里的类

1.5.1 实例化热更里无参构造函数的类

        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass");

或者

        //预先获得IMethod,可以减低每次调用查找方法耗用的时间
        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        object obj = ((ILType)type).Instantiate();

1.5.2 实例化热更里有参构造函数的类


        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass",new object[] {
    
     123 });

或者

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        object obj = ((ILType)type).Instantiate(new object[] {
    
     321 });

2.获取IMethod后再调用

预先获得IMethod,可以减低每次调用查找方法耗用的时间

2.1 有参静态方法

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        IMethod method = type.GetMethod("StaticFunTest2", 1);
        appdomain.Invoke(method, null, 123);

2.2 有参非静态方法

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass", new object[] {
    
     123 });
        IMethod method = type.GetMethod("FunTest2", 1);
        appdomain.Invoke(method, obj, 222);

3.无GC Alloc方式调用方法

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass", new object[] {
    
     123 });
        IMethod method = type.GetMethod("FunTest2", 1);
        using (var ctx = appdomain.BeginInvoke(method))
        {
    
    
            ctx.PushObject(obj);
            ctx.PushInteger(223);
            ctx.Invoke();
        }

4.调用成员方法

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass", new object[] {
    
     233 });
        IMethod 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);
        }

这里的ReadInteger()读取的是返回值 retrun id

5.范型方法调用

5.1 调用泛型方法
主工程:

        IType stringType = appdomain.GetType(typeof(string));
        IType[] genericArguments = new IType[] {
    
     stringType };
        appdomain.InvokeGenericMethod("HotFix_Project.InstanceClass", "GenericMethod", genericArguments, null, "TestString");

热更工程:

        public static void GenericMethod<T>(T a)
        {
    
    
            UnityEngine.Debug.Log("!!! InstanceClass.GenericMethod(), a=" + a);
        }

5.2 获取泛型方法的IMethod

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        //参数类型列表
        List<IType> paramList = new List<ILRuntime.CLR.TypeSystem.IType>();
        IType intType = appdomain.GetType(typeof(int));
        IType stringType = appdomain.GetType(typeof(string));
        IType[] genericArguments = new IType[] {
    
     stringType };
        paramList.Add(intType);
        genericArguments = new IType[] {
    
     intType };
        IMethod method = type.GetMethod("GenericMethod", paramList, genericArguments);
        //appdomain.Invoke(method, null, 33333);
        using(var ctx = appdomain.BeginInvoke(method))
        {
    
    
            ctx.PushInteger(22333);
            ctx.Invoke();
        }

6.Ref/Out方法调用

        IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"];
        IMethod method = type.GetMethod("RefOutMethod", 3);
        object obj = appdomain.Instantiate("HotFix_Project.InstanceClass", new object[] {
    
     345 });
        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));
        }

二、在热更里调用主工程的方法

1.引用对应的DLL

Assembly-CSharp.dll 所有我们写在Asset下的所有脚本
UnityEngine.CoremMdule等
位置:/Applications/unityHub/2019.4.31f1c1/Unity.app/Contents/Managed/UnityEngine/x x x.dll

2.直接调用

引用,然后就可以直接调用了

3.注意类型和方法的保护等级

猜你喜欢

转载自blog.csdn.net/weixin_45724919/article/details/129451964