在以往的Unity项目热更方案中,无论是lua还是ilruntime,都是基于独立vm与原生AOT(静态编译)代码进行交互(各种wraper)。现在出现了一个全新的热更方案,HybridCLR。
HybridCLR方案实现方式与ilruntime类似,都是对dll进行更新,都需要对dll进行解释。区别在于HybrtidCLR没有vm的概念,对于原生ATO接口就直接取函数指针进行调用,对于新增加的函数,由于不能执行新生成的机器码(ios上),所以自定义了一套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执行时创建新增的元数据类型
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; }
标签:__,index,ip,HybridCLR,il2cpp,uint16,初探 From: https://www.cnblogs.com/hghhe/p/16739575.html