热更新 ILRuntime 从零开始 委托 Delegate

Posted 水光涵月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了热更新 ILRuntime 从零开始 委托 Delegate相关的知识,希望对你有一定的参考价值。

小姐姐镇楼,便于通过图片查找文章,

我们继续来一起看下ILRuntime的第三个案例———Delegate:委托。
这是这一系列文章的总目录链接
🏺有疑问的可以先看下之前的文章。



🎁委托适配器(DelegateAdapter)和委托转换器(DelegateConvertor)

如果只在热更新的DLL项目中使用的委托,是不需要任何额外操作的,就跟在通常的C#里那样使用即可如果你需要将委托实例传给ILRuntime外部使用,那则根据情况,你需要额外添加适配器或者转换器。
如果在运行时发现缺少注册某个指定类型的委托适配器或者转换器时,ILRuntime会抛出相应的异常,根据提示添加注册即可。

🌲1.委托适配器(DelegateAdapter)

如果将委托实例传出给ILRuntime外部使用,那就意味着需要将委托实例转换成真正的CLR(C#运行时)委托实例,这个过程需要动态创建CLR的委托实例。由于IL2CPP之类的AOT编译技术无法在运行时生成新的类型,所以在创建委托实例的时候ILRuntime选择了显式注册的方式,以保证问题不被隐藏到上线后才发现。委托适配器的具体用法会在下面的例子里面看到。

🌲2.委托转换器(DelegateConvertor)

ILRuntime内部是使用Action,以及Func这两个系统自带委托类型来生成的委托实例,所以如果你需要将一个不是Action或者Func类型的委托实例传到ILRuntime外部使用的话,除了委托适配器,还需要额外写一个转换器,将Action和Func转换成你真正需要的那个委托类型。委托转换器的具体用法会在下面的例子里面看到。

🎁一、自定义带参数无返回值的委托

在官方的例子DelegateDemo.cs中,讲的就是委托相关的用法。
声明带参数无返回值的委托

public delegate void TestDelegateMethod(int a);
public static TestDelegateMethod TestMethodDelegate;

InitializeILRuntime()方法中去注册,这里就用到了 注册委托适配器

//TestDelegateMethod, 这个委托类型为有个参数为int的方法,注册仅需要注册不同的参数搭配即可
        appdomain.DelegateManager.RegisterMethodDelegate<int>();

上面也说了,ILRuntime内部是使用Action,以及Func这两个系统自带委托类型来生成的委托实例,所以在涉及到自定义委托的时候,就要用到委托转换器了,下面就是委托转换器的写法

//ILRuntime内部是用Action和Func这两个系统内置的委托类型来创建实例的,所以其他的委托类型都需要写转换器
        //将Action或者Func转换成目标委托类型

        appdomain.DelegateManager.RegisterDelegateConvertor<TestDelegateMethod>((action) =>
        {
            //转换器的目的是把Action或者Func转换成正确的类型,这里则是把Action<int>转换成TestDelegateMethod
            return new TestDelegateMethod((a) =>
            {
                //调用委托实例
                ((System.Action<int>)action)(a);
            });
        });

再来看下ILRuntime工程这边的TestDelegate.cs设置委托实例的引用

🌲1.ILRuntime工程的委托实例,设置引用方法

 public static void Initialize()
        {
            delegateMethod = Method;
            delegateFunc = Function;
            delegateAction = Action;
        }

🌲2.Unity工程的委托实例,设置引用方法

 public static void Initialize2()
        {
            DelegateDemo.TestMethodDelegate = Method;
            DelegateDemo.TestFunctionDelegate = Function;
            DelegateDemo.TestActionDelegate = Action;
        }

🎁二、自定义带参数有返回值的委托

声明带参数有返回值的委托

public delegate string TestDelegateFunction(int a);
public static TestDelegateFunction TestFunctionDelegate;

InitializeILRuntime()方法中去注册,同上也用到了 注册委托适配器

//带返回值的委托的话需要用RegisterFunctionDelegate,返回类型为最后一个
        appdomain.DelegateManager.RegisterFunctionDelegate<int, string>();

ILRuntime工程这边的TestDelegate.cs设置委托实例的引用

🎁三、系统内置Action和Func委托

用Action或者Func当作委托类型的话,可以避免写转换器,所以项目中在不必要的情况下尽量只用Action和Func

🌲1.Action

Action适用于只有参数无返回值的委托

🌲2.Func

Action适用于有参数有返回值的委托

🎁三、在Unity工程中调用

OnHotFixLoaded()方法中调用

//设置引用方法
appdomain.Invoke("HotFix_Project.TestDelegate", "Initialize2", null, null);
        appdomain.Invoke("HotFix_Project.TestDelegate", "RunTest2", null, null);
        //无返回值委托调用
         TestMethodDelegate(789);
         //有返回值委托调用
        var str = TestFunctionDelegate(098);
        Debug.Log("!! OnHotFixLoaded str = " + str);
        //Action的调用
        TestActionDelegate("Hello From Unity Main Project");

实际运行返回的结果如下:

🎁建议

为了避免不必要的麻烦,以及后期热更出现问题,建议项目遵循以下几点:
🏺尽量避免不必要的跨域委托调用
🏺尽量使用Action以及Func这两个系统内置万用委托类型


总结

欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。
如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~

声明:本博文章若非特殊注明皆为原创原文链接
https://blog.csdn.net/Wrinkle2017/article/details/120513040
————————————————————————————————

💢💢版权声明

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

以上是关于热更新 ILRuntime 从零开始 委托 Delegate的主要内容,如果未能解决你的问题,请参考以下文章

unity-ilruntime热更新

unity-ilruntime热更新

unity-ilruntime热更新

unity-ilruntime热更新

Unity ILRuntime热更新开发原则与接口如何绑定

unity热更新新方案,ILRuntime