cat
Shioho

# 注意事项

# 委托类型的绑定

在主工程中调用热更工程的代码时,需要绑定委托适配器委托转换器

  • 委托适配器:如果将委托实例传出给 ILRuntime 外部使用,那就意味着需要将委托实例转换成真正的 CLR(C# 运行时)委托实例,这个过程需要动态创建 CLR 的委托实例。由于 IL2CPP 之类的 AOT 编译技术无法在运行时生成新的类型,所以在创建委托实例的时候 ILRuntime 选择了显式注册的方式,以保证问题不被隐藏到上线后才发现。
    同一个参数组合的委托,只需要注册一次即可,例如:
cs
delegate void SomeDelegate(int a, float b);
Action<int, float> act;

这两个委托都只需要在 ILRuntimeDelegateHelper.cs 注册一个适配器即可。 注册方法如下

cs
appDomain.DelegateManager.RegisterMethodDelegate<int, float>();

如果是带返回类型的委托,例如:

cs
delegate bool SomeFunction(int a, float b);
Func<int, float, bool> act;

需要按照以下方式注册

cs
appDomain.DelegateManager.RegisterFunctionDelegate<int, float, bool>();
  • 委托转换器:ILRuntime 内部是使用 Action, 以及 Func 这两个系统自带委托类型来生成的委托实例,所以如果你需要将一个不是 Action 或者 Func 类型的委托实例传到 ILRuntime 外部使用的话,除了委托适配器,还需要额外写一个转换器,将 Action 和 Func 转换成你真正需要的那个委托类型。比如上面例子中的 SomeFunction 类型的委托,其所需的 Convertor 应如下实现:
s
appdomain.DelegateManager.RegisterDelegateConvertor<SomeFunction>((action) =>
        {
            return new SomeFunction((a, b) =>
            {
                return ((Func<int, float, bool>)action)(a, b);
            });
        });

为了避免不必要的麻烦,以及后期热更出现问题,建议项目遵循以下几点:

  • 尽量避免不必要的跨域委托调用
  • 尽量使用 Action 以及 Func 这两个系统内置万用委托类型

# 无法使用的写法

以下写法会导致无法打成 dll,需注意:

  • 经过测试 ref List不宜当做参数取返回值,否则方法连调用都不能调用
  • 自定义类型的二维数据使用会报错 ( Cannot find method:.ctor in type:Point2 [0...,0...], token=System.Void Point2 [0...,0...]::.ctor (System.Int32,System.Int32))
  • for 层次太深在协程里也会报错,非协程还不知道。
  • 结构体数组会出现在数组范围内的索引给报越界的情况,可以用 class 类数组
  • LitJson 解析 List 里的类时,若类里包含枚举类型,且该枚举类型使用了 get,set,则该枚举类型在 dll 打包使用时会为空
  • Linq 的列表排序会导致打包失败. (原因是没有添加委托适配器)
unlockCardDic = unlockCardDic.OrderByDescending(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

汘帆 微信

微信

汘帆 支付宝

支付宝