CS5L3——Unity跨平台的基本原理之IL2CPP

本章主要内容

  1. IL2CPP是什么
    是Unity4.6.1版本之后加入的新的一种跨平台解决方案
  2. Mono跨平台回顾
    C#代码—>Mono C#编译器—>IL中间代码—>Mono VM—>操作系统的原生代码
  3. IL2CPP跨平台原理
    C#代码—>Mono C#编译器—>IL中间代码—>IL2CPP—>C++—>C++编译器—>原生汇编代码—>IL2CPP VM
  4. Mono和IL2CPP的区别
    IL2CPP效率高于Mono,跨平台也更好维护。
    Mono是JIT即时编译,IL2CPP是AOT提前编译
  5. Mono和IL2CPP两种方式的使用建议
    建议使用效率更高的IL2CPP

IL2CPP

IL2CPP 是在 Unity4.6.1 p5 之后的版本中加入的脚本后处理方式
你可以把它简单理解为是:继Mono之后的一种跨平台解决方案
顾名思义就是把 IL中间代码 转译为 CPP代码(C++)

想要了解它我们可以先回顾一下Mono,Mono的优缺点回顾

IL2CPP跨平台原理

通过IL2CPP我们可以将编译好的IL中间代码转译成C++代码
再利用各平台优化过的编译器编译为对应平台的目标代码

image

IL2CPP和Mono的区别就在于:
当生成了IL中间代码后,Mono是直接通过虚拟机转译运行
而IL2CPP的步骤多了一些:会将IL中间代码转译为C++代码
再通过各平台的C++编译器直接编译为可执行的原生汇编代码

image

需要注意的是:
虽然中间代码变为了C++,但是内存管理还是遵循C#中GC的方式,
这也是为什么有一个IL2CPP VM(虚拟机)存在的原因,它主要是用来完成GC管理,线程创建等服务工作的

Mono与IL2CPP的区别

  • Mono

    1. 构建(最终打包时)速度快
    2. Mono编译机制是JIT即时编译,所以支持更多类库
    3. 必须将代码发布为托管程序集(.dll文件)
    4. Mono VM虚拟机平台维护麻烦,且部分平台不支持(WebGL)
    5. 由于Mono版本授权原因,C#很多新特性无法使用
    6. IOS支持Mono,但不再允许32位的Mono应用提交到应用商店
  • IL2CPP

    1. 相对Mono构建(最终打包时)速度慢
    2. 只支持AOT提前编译
    3. 可以启用引擎代码剥离来减少代码的大小
    4. 程序的运行效率比Mono高,运行速度快
    5. 多平台移植更加方便

Mono和IL2CPP的最大区别就是:IL2CPP不能在运行时动态生成代码和类型,所以必须在编译时就完全确定需要用到的类型

举例:
List<A>​ 和 List<B>​ 中A和B是我们自定义的类,
我们必须在代码中显式的调用过它们(声明并new A和B) ,IL2CPP才能保留 List<A>​ 和 List<B>​ 两个类型。
如果在热更新时我们调用 List<C>​,但是它之前并没有在代码中显示调用过,那么这时就会出现报错等问题。
主要就是因为 JIT 和 AOT 两个编译模式的不同造成的,具体的解决方案我们在下节课中讲解

Mono和IL2CPP的使用建议

由于IL2CPP的运行效率有很大优势,所以建议大家在实际开发中直接使用IL2CPP模式进行打包

补充:什么是AOT

AOT(Ahead-Of-Time)就是提前编译,在程序运行之前将代码编译成机器码。
这意味着在程序执行前,所有代码已经被转换为可以直接在目标机器上运行的格式。
AOT 具有启动速度快、内存占用低、无需运行时编译等优点,AOT 编译的性能一般也会好于 JIT。
但是,AOT也有无运行时优化、灵活性差等问题。