HybridCLR初探
在以往的Unity项目热更方案中,无论是lua还是ilruntime,都是基于独立vm与原生AOT(静态编译)代码进行交互(各种wraper)。现在出现了一个全新的热更方案,HybridCLR。
HybridCLR方案实现方式与ilruntime类似,都是对dll进行更新,都需要对dll进行解释。区别在于HybrtidCLR没有vm的概念,对于原生ATO接口就直接取函数指针进行调用,对于新增加的函数进行解释执行,所以自定义了一套IL指令的执行方法(dll中其实就是许多的IL指令结构,当然为了更高效率HybridCLR将IL指令集转换成自己的指令集)。类似:BinOpVarVarVar_Add_i4 指令的实际实现:
case HiOpcodeEnum::BinOpVarVarVar_Add_i4: { uint16_t __ret = *(uint16_t*)(ip + 2); uint16_t __op1 = *(uint16_t*)(ip + 4); uint16_t __op2 = *(uint16_t*)(ip + 6); (*(int32_t*)(localVarBase + __ret)) = (*(int32_t*)(localVarBase + __op1)) + (*(int32_t*)(localVarBase + __op2)); ip += 8; continue; }
HybridCLR相对于lua热更方案有以下优点:
1. 游戏中只需要编写一种代码,且与Unity自身调用效率更高(直接调用AOT代码,不需要warper)
2. 可动态新增加数据类型(如新的MonoBehaviour而不需要重新打整包),此项HybridCLR是通过修改il2cpp工具实现的,在il2cpp执行时创建新增的元数据类型。
unity打包后会将所有的元数据类型定义到Data\Managed\Metadata\global-metadata.dat, il2cpp默认只认这个文件中已定义的元数据类型。
const char* il2cpp::vm::GlobalMetadata::GetStringFromIndex(StringIndex index) { // 新增元数据给予特殊标记 if (huatuo::metadata::IsInterpreterIndex(index)) { return huatuo::metadata::MetadataModule::GetStringFromEncodeIndex(index); } // 原始il2cpp的元数据获取 IL2CPP_ASSERT(index <= s_GlobalMetadataHeader->stringSize); const char* strings = MetadataOffset<const char*>(s_GlobalMetadata, s_GlobalMetadataHeader->stringOffset, index); #if __ENABLE_UNITY_PLUGIN__ if (g_get_string != NULL) { g_get_string((char*)strings, index); } #endif // __ENABLE_UNITY_PLUGIN__ return strings; }
3. 调用unity接口更方便,各种泛型接口都可调用
4. 代码调试更方便,不再需要其它额外的调试工具
那么HybridCLR有没有缺点呢?当然是有的。
1. 如在游戏中进行代码更新,则需要重新启动游戏,因为dll不支持reload。当然我们可以在加载dll之前先处理更新来避免这个问题,但更新相关代码将不能被更新。
2.如项目中新加了dll(打包时已定义的dll不受影响),则新的dll中的脚本不能直接挂载到prefab上(无法初始化),但可以通过代码创建这些脚本。
3. 由于HybridCLR需要读取AOT的元数据,而这些元数据dll在裁剪后打包时可能会发生变化,这将导致出现元数据不匹配报错。例如在1.1版本生成的mcrolib.dll与1.0版本生成mcrolib.dll不一致,则将1.1版本的资源包更新给1.0的整包,将运行报错。解决办法是更新资源时特殊处理,不更新这些AOT对应的dll。不过这个问题官方说将来会解决掉。
4. 这个热更方案很依赖官方的更新,官方需要紧跟Unity版本不断适配il2cpp工具,当然如果unity直接底层支持此方案就完美了。
综上HybridCLR热更方案确实有很大的吸引力,如后续逐渐稳定,一定会被越来越多的人使用。
参考:
关于HybridCLR可行性的思维实验:https://zhuanlan.zhihu.com/p/528326040
HybridCLR技术原理剖析:https://zhuanlan.zhihu.com/p/531468413