|
原理
- huatuo扩充了il2cpp的代码,使它由纯AOT runtime变成 AOT+Interpreter 混合runtime,进而原生支持动态加载assembly,使得基于il2cpp backend打包的游戏不仅能在Android平台,也能在IOS、Consoles等限制了JIT的平台上高效地以 AOT+interpreter 混合模式执行,从底层彻底支持了热更新。
- huatuo是原生的c#热更新方案。通俗地说,il2cpp相当于mono的AOT模块,huatuo相当于mono的interpreter模块,两者合一成为完整mono。huatuo使得il2cpp变成一个全功能的runtime,原生(即通过System.Reflection.Assembly.Load)支持动态加载dll,从而支持ios平台的热更新。
- huatuo的基本原理非常简单,对于AOT的代码就使用IL2CPP执行,对于非AOT代码(比如我们提供的dll)则通过huatuo解释执行。如下图所示:
huatuo基本原理
缺点
- huatuo刚出现不久,还未到beta版本,每天都可能会更新,不稳定。但是由于huatuo技术原理的先进性,bug本质不多,稳定得非常快。而且huatuo的作者在[QQ群](## huatuo交流群)很方便就能沟通上,也很积极地在解决出现的问题。
- 采用huatuo的项目极少,还没有已知的商业项目采用huatuo。
- 目前huatuo工作流欠缺。没有类似ILRuntime的CLR绑定,也没有类似ILRuntime在缺少Delegate时候的泛型友好提示。
- 因为huatuo刚出,兼容性测试比较少,还未测试是否可以把项目成功编译打包到所有平台并顺利运行。
- 暂时不支持真机上的c#源码调试,但可以自己断点跟踪huatuo指令集的执行过程。另外editor下直接使用mono的调试方式。
- 有些第三方库的dll会因为il2cpp的原因而被自动剪裁掉,进而导致第三方库il2cpp编译失败,需要注意。比如交流群中有人表示,Unity DOTS会被il2cpp剪裁,导致huatuo无法热更。
- 无论哪个框架和库,都必然有huatuo对AOT泛型的限制问题。AOT泛型有少量限制,无法创建出普通AOT泛型(delegate、Nullable、数组(包括多维)不受限制,热更新泛型也完全不受限)的热更新非枚举值类型的实例化类型的实例。 例如不支持List但支持List、List和List。(参见泛型文档)
- 不支持delegate的BeginInvoke和EndInvoke函数。无用,故意不支持。
- 不支持extern函数 (后面会支持)
- 不支持在运行时重新加载程序集。但可以加载多个程序集或加载新修改的程序集。
特性
- 正因为huatuo是原生runtime级别实现,热更新部分的类型与主工程AOT部分类型是完全等价并且无缝统一的。可以随意调用、继承、反射、多线程,不需要生成代码或者写适配器。
- 原生支持hotfix修复AOT部分代码。几乎不增加任何开发和运行开销。
- 支持很多特性,比如:
- 支持热更新部分的泛型类和泛型函数。
- 支持热更新值类型的数组类型,任何维都支持。
- 支持多维数组。
- 支持可空变量。
- 支持热更新MonoBehaviour。不仅能在代码中添加,也可以直接挂在热更新资源上。
- 支持反射。
- 支持多线程。支持Thread, Task, volatile, ThreadStatic, async(部分受限)。
- 支持多Assembly,最大支持63个。但是不会自动加载依赖dll。需要你手动按依赖顺序加载热更dll。
- 支持IEnumerator。
- 支持创建值类型。
- 支持注解。
- 支持 api compatible level .net standard 2.0,但请注意,主工程和热更新工程的api compatible要一致。
性能
时间效率测试
时间效率
内存效率测试
内存效率
兼容性
Unity版本
- 2019之前不支持,除非给作者打钱。2019只支持2019.4.37版本。2020和2021的如果需要支持某个未支持的小版本,请联系作者,免费提供小版本适配的指导。
- 目前支持2019.4.37,2020.3.7, 2020.3.9,2020.3.33,2021.3.0, 2021.3.1版本。
- unity版本推荐。推荐使用2020系列,最稳定。2019属于支持,但很快废弃的版本;2021版本Unity还有大量bug,作者正谨慎跟进。
平台兼容性
- huatuo扩充了il2cpp的代码,使它由纯AOT runtime变成 AOT+Interpreter 混合runtime,进而原生支持动态加载assembly,使得基于il2cpp backend打包的游戏不仅能在Android平台,也能在IOS、Consoles等限制了JIT的平台上高效地以AOT+interpreter混合模式执行。从底层彻底支持了热更新。
- 因为huatuo刚出,兼容性测试比较少,还未经过大量测试是否可以把项目成功编译打包到所有平台并顺利运行。
- 暂时不支持真机上的c#源码调试,但可以自己断点跟踪huatuo指令集的执行过程。另外editor下直接使用mono的调试方式。
- 真机测试前强烈推荐先调通win版本。由于很容易遇到类型裁剪及AOT泛型实例化引发的问题,推荐先在Win版本测试通过了,再打android和ios包,能极大节省时间。
- iOSBuild官方文档
- 其他网友使用huatuo在多平台上打包时遇到的问题:
[Mac] 打包的Mac项目报找不到imageplayersetting里面需要把ios也选上.NET 4.x。[Android] * error only support 64bit。顾命思议,playsetting那边勾选arm64,自己的SDK工程中的Gradle也需要进行对应的64位调整:ndk {abiFilters 'arm64-v8a'}
第三方库兼容性
- protobuf-net库的Dictionary无法使用,这个问题纯AOT下也存在,非huatuo问题。因为MapDecorator是internal,无法提前构造AOT的泛型实例。如果非要用,解决办法是修改源码,改成public,然后再提前构造它的泛型实例化类型。
- protobuf 3.19.4库的map类型需要提前注册 MapField及MapField.Codec。
使用注意
- 每天都要先pull一下huatuo工程以及il2cpp_huatuo工程,然后按照[文档](## huatuo安装和环境搭建 )替换unity的libil2cpp。
- AOT-interpreter 桥接函数。huatuo的interpreter与AOT之间需要双向函数调用。比如,interpreter调用AOT函数,或者AOT部分有回调函数会调用解释器部分。
- 支持2019-2022全系列版本,但不是每个小版本都支持。具体请查看现在支持的Unity版本。
- 支持 .net standard 2.0,但要求打主工程包用.net standard,打热更新dll用.net 4.x。原因是unity使用.net standard发布后,会自动剥去.net standard,导致类型找不到。
- 需要提前做好防剪裁,提前生成对应的泛型代码。
- 无法创建出普通AOT泛型(delegate、Nullable、数组(包括多维)不受限制,热更新泛型也完全不受限)的热更新非枚举值类型的实例化类型的实例。 例如不支持List但支持List、List和List。 具体原因见AOT泛型限制及原理介绍。这个会在7月份版本比较彻底地解决,此后不再有限制。
- 暂时不支持返回自定义值类型的默认async task。async void及原生值类型如int及枚举及class类型不受限制。原因是编译器会为async默认生成 AsyncTaskMethodBuilder的泛型类实例化,如果像ETask那样使用自定义Task及AsyncTaskMethodBuilder,则不受限制。原生async这个限制后续版本会解决。
- 注意使用link.xml或者代码引用的方式避免unity裁减代码。避免开发期能调用,发布后却找不到函数的错误。我们后续会提供默认模板。
- 不支持delegate的BeginInvoke, EndInvoke。纯粹是觉得没必要实现。
- 在资源中挂载热更新脚本需要在打包时做少量特殊处理,参见MonoBehaviour相关工作流。
- 暂不支持增量式gc。由于时间紧凑,来不及仔细处理增量式gc的memory barrier细节。这个问题很快会解决。
- 真机测试前强烈推荐先调通win版本。由于很容易遇到类型裁剪及AOT泛型实例化引发的问题,推荐先在Win版本测试通过了,再打android和ios包,能极大节省时间。
- 暂时不支持打包后真机的c#源码调试,但能打印错误堆栈(只能精确到函数),也可以在Build出的Debug工程中跟踪调试。Editor下开发期调试使用平时的mono调试就可以了。
- huatuo的运行是基于il2cpp的,所以对于在Editor下运行的代码是没有使用huatuo的。要使用huatuo需要打包后运行。
- 热更新dll不能直接从 Library/ScriptAssemblies 复制,因为它没有正确使用相应平台的编译开关。正确的实现请参考 huatuo_trail 项目 的 HuatuoEditorHelper中的CompileDll 函数。
- 推荐将启动脚本挂载到启动热更新场景,这样可以零改动将非热更新工程改造成热更新工程,还不需要任何反射操作。
- 原生与解释器部分性能敏感的场合不要用反射来交互,应该通过Delegate。
- 常见错误官方文档。
huatuo安装和环境搭建
huatuo交流群
- huatuo使用疑难咨询 QQ 428404198
- huatuo c#热更新 QQ 651188171
烟雨迷离半世殇对huatuo的评价
划时代的代码热更新方案huatuo源码流程解析
烟雨迷离半世殇
huatuo和ILRuntime
- 通俗地说,il2cpp相当于mono的AOT模块,huatuo相当于mono的interpreter模块,两者合一成为完整mono。ILRuntime相当于独立vm,与il2cpp的关系本质上相当于mono中嵌入lua的关系。因此类型系统不统一,为了让热更新类型能够继承AOT部分类型,需要写适配器,并且解释器中的类型不能为主工程的类型系统所识别。特性不完整、开发麻烦、运行效率低下。huatuo使得il2cpp变成一个全功能的runtime,原生(即通过System.Reflection.Assembly.Load)支持动态加载dll,从而支持ios平台的热更新。Huatuo热更新部分的类型与主工程AOT部分类型是完全等价并且无缝统一的。可以随意调用、继承、反射、多线程,不需要生成代码或者写适配器。
- huatuo学习和使用成本几乎为零。huatuo 让il2cpp变成全功能的mono,学习和使用成本几乎为零,几乎零侵入性。而其他方案则有大量的坑和需要规避的规则,学习和使用成本,需要对原项目作大量改造。
- huatuo可以使用所有c#的特性。而其他方案往往有大量的限制。
- huatuo中可以直接支持使用和继承主工程中的类型。其他方案要写适配器或者生成代码。
- huatuo中热更新类型与主工程的AOT类型无缝统一。huatuo中反射代码能够正常工作的,主工程部分也可以通过标准Reflection接口创建出热更新对象。其他方案做不到。
- huatuo对多线程支持良好。像多线程、ThreadStatic、async等等特性都是huatuo直接支持,其他方案除了async特性外均难以支持。
- huatuo中Unity工作流与原生几乎完全相同。huatuo中热更新MonoBehaviour可以直接挂载在热更新资源上,并且正确工作。其他方案不行。
- huatuo兼容性极高。各种第三方库只要在il2cpp下能工作,在huatuo下也能正常工作。其他方案往往要大量魔改源码。但是有些第三方库的dll会因为il2cpp的原因而被自动剪裁掉,进而导致第三方库il2cpp编译失败,需要注意。
- huatuo内存效率极高。huatuo中热更新类型与主工程的AOT类型完全等价,占用一样多的空间。其他方案的同等类型则是假类型,不仅不能被runtime识别,还多占了数倍空间。
- huatuo执行效率高。huatuo中热更新部分与主工程AOT部分交互属于il2cpp内部交互,效率极高。而其他方案则是独立虚拟机与il2cpp之间的效率,不仅交互麻烦还效率低下。
- ILRuntime在使用中要频繁的添加适配器;频繁的添加委托;AOT裁减。就目前而言huatuo宣称上能够很好的解决以上的部分问题,使用起来简易不少。问题比较大就是对il2cpp的代码入侵较大,在没有成功上线项目下感觉要趟不少坑。
参考链接
https://github.com/focus-creative-games/huatuohttps://github.com/pirunxi/il2cpp_huatuohttps://github.com/focus-creative-games/huatuo_trialhttps://github.com/focus-creative-games/huatuo_upmhttps://github.com/focus-creative-games/huatuo/wiki/https://www.bilibili.com/video/BV13a411a7SQhttps://www.bilibili.com/video/BV1wF411j7bThttps://zhuanlan.zhihu.com/p/513834841https://www.lfzxb.top/huatuo-source-analyze/https://github.com/focus-creative-games/huatuo/issues?q=is%3Aissue+is%3Aclosedhttp://lipenghui.github.io/2022/04/02/%E7%83%AD%E6%9B%B4%E6%96%B0%E6%96%B9%E6%A1%88%E3%80%8Ahuatuo%E3%80%8B%E5%B0%9D%E9%B2%9C/
本文使用 Zhihu On VSCode 创作并发布
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|