CLR:Common Language Runtime
中文叫公共语言运行时。是让 .NET 程序执行所需的外部服务的集合,.NET 平台的核心和最重要的组件,类似于 Java 的 JVM。
script backend
- mono:只支持32位
- il2cpp:支持32位和64位,跨平台性更好
il2cpp和mono相比的特点:
- 可以调试生成的C ++代码。
- 可以启用引擎代码剥离(Engine code stripping)来减少代码的大小。
- 程序的运行效率比Mono高,运行速度快。
- 多平台移植非常方便。
- 相比Mono构建应用慢。
il2cpp
il2cpp是Unity开发的跨平台CLR解决方案。它产生的一个关键原因是Unity需要跨平台运行,但一些平台如iOS这种禁止了JIT,导致依赖了JIT的官方CLR虚拟机无法运行,必须使用AOT技术将mananged程序提前转化为目标平台的静态原生程序后再运行。而mono虽然也支持AOT,但性能较差以及跨平台支持不佳。il2cpp方案包含一套AOT运行时以及一套dll到C++代码及元数据的转换工具,使得原始的c#开发的代码最终能在iOS这样的平台运行起来。
il2cpp与热更新
很不幸,不像mono有Hybrid mode execution,支持动态加载dll,il2cpp是一个纯静态的AOT运行时,不支持运行时加载dll,因此不支持热更新。目前unity平台的主流热更新方案xlua、ILRuntime之类都是引入一个第三方vm(virtual machine),在vm中解释执行代码,来实现热更新。限于篇幅我们只分析使用c#为开发语言的热更新方案。这些热更新方案的vm与il2cpp是独立的,意味着它们的元数据系统是不相通的,在热更新里新增一个类型是无法被il2cpp所识别的(例如通过System.Activator.CreateInstance是不可能创建出这个热更新类型的实例),这种看起来像、实际上却又不是的伪CLR虚拟机,在与il2cpp这种复杂的CLR运行时交互时,产生极大量的兼容性问题,另外还有严重的性能问题。一个大胆的想法是,是否有可能对il2cpp运行时进行扩充,添加interpreter模块,进而实现mono hybrid mode execution 这样机制?这样一来就能彻底支持热更新了,并且兼容性极佳。对开发者来说,除了以解释模式运行的部分执行得比较慢,其他方面跟标准的运行时没有区别。对il2cpp加以了解并且深思熟虑后的答案是——确实是可行的!具体分析参见 关于HybridCLR可行性的思维实验 。这个想法诞生了HybridCLR,unity平台第一个支持ios的跨平台原生c#热更新方案!