unity python热更新_Unity实现c#热更新方案探究(二)

一、IOS对DLL热更新的禁止

紧接上文,继续对C#热更新的研究。上文中,已经说了如何基于appDomain来实现对DLL的加载和卸载,进一步,可以在unity工程中,将Dll打包成资源,通过Assembly.Load的方式加载DLL来实现更新。那么为什么IOS中就不能这样操作了呢?

推荐阅读文章:

这两篇文章,对整个IOS不能热更新的缘由,有详细的讲解,对于Mono的JIT编译模式和AOT编译模式也有讲解。总结来说,代码是可以在IOS中动态生成的,只是IOS为了安全性的考虑,禁止了内存的操作权限,因此JIT这种编译模式,在IOS平台上,Mono会自己禁止了,只能使用Full AOT(非Full AOT的编译模式下,部分代码也会支持JIT,所以必须Full AOT)的编译模式。

既然不能JIT的编译,那么我们就不能基于Assembly.Load来加载DLL的bytes了。如何解决这个问题?让我们看看ILRuntime的解决思路。

二、ILRuntime基于IL虚拟机实现对DLL的热更新

首先看看ILRuntime对于其实现原理的解释:

ILRuntime借助Mono.Cecil库来读取DLL的PE信息,以及当中类型的所有信息,最终得到方法的IL汇编码,然后通过内置的IL解译执行虚拟机来执行DLL中的代码

那么,我们逐步来分析这些操作过程是如何执行的。

1、借助Mono.Ceil库来读取DLL的PE信息以及当中类型的所有信息

这一步是如何实现的,跟随源代码做一个详细的跟踪。

首先,是构建一个全局的appDomain(这儿不是程序域的意思,只是取其名字意思来表示)

基于WWW的方式加载AssetBundle或者DLL/PDB后,接下来是将其封入到MemoryStream中,将dll和pdb的bytes都存入到内存流中后,执行其内部实现的LoadAssembly方法。

关键的是第一行,从Mono中加载模块:

进一步跟踪:

ReadImageFrom的操作:

其中ImageReader最终来自BinaryReader:

那么接下来的ReadImage操作:

这四个操作,是最核心的操作,分别读取DLL的PE的各个信息,这样我们就进入下一个步骤。

2、最终得到方法的IL汇编码

让我们分拆来看看这几个读取函数的实现

1)ReadOptionalHeaders

主要读取PE的相关信息,不做过多解释,可以参看源码阅读理解;

2)ReadSections

读取分块数据,

封装一个Section,然后去执行读取,然后赋值给section的Data,注意回退了Index

3)ReadCLIHeader

这步比较简单

4) ReadMetadata

核心是两个操作,一个是ReadMetadataStream,就是根据不同的标识符来新建不同的存储结构;一个是ReadTableHeap:

初始化heap中的Table后,进行一次Compute,获取size:

然后填充size:

基于这四步操作,我们可以将IL的汇编码存储到Image中,然后进一步执行后续的CreateModule操作:

具体到,就是:

其中的ReadModule为:

具体的读取manifest和Module内部数据,可以参看源码。

读取完module后,我们下一篇文章再详细讲解如何执行IL语句,这篇文章先写到这儿吧 :D

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值