Unity 热更新为啥用Lua 详解

他们说

  阅读了网上一些文章,其实使用C#进行热更新是可以的,将需要更新的代码打包成程序集,然后利用反射即可,但是也提到在IOS平台是不行的,至于为什么不行,就不再说了,然后就是推荐Lua作为热更新方案,但是,为啥Lua就行?C#就不行?

因为C#是编译型语言,Lua是解释型语言?

  好多人都说Lua能热更新,是因为它是解释型语言,不用编译,在运行时能动态解释Lua代码并运行。这种方法实际上不准确,从某些角度来说是错的。Lua确实是解释性脚本语言,但是不是因为是解释型才能进行热更新。即使使用C++这种编译语言,也能进行热更新,将动态链接库进行更新就是,然后动态加载动态链接库获取更新的函数地址即可。

  而且,还有一点,C#并不能说是一种编译型语言,C#代码会被编译成IL,IL解释成机器码的过程可以在运行之前进行也能在运行时进行。如果在运行时进行解释,那么和Lua不就一样了吗,为啥C#不能进行热更新呢?

JIT对IL进行解释执行的原理

  首先说一下,JIT对IL如何在运行时进行解释并执行的,大致过程为:将IL解释为所在平台的机器码,开辟一段内存空间,要求这段内存空间可读、可写、可执行,然后把解释出的机器码放入,修改CPU中的指令指针寄存器中的地址,让CPU执行之前解释出来的机器码。

  注意这段内存的条件,最重要的一条是必须是可执行的,一般的内存申请我们只是存放数据,但是这里的内存权限要是有可执行权限

IOS限制了什么?

  IOS不允许获取具有可执行权限的内存空间,这就直接要求JIT要以full AOT模式,这种模式会在生成之前把IL直接翻译成机器码而不是在运行期间,进行了这种操作C#从某种角度来说和C++一样,成为了编译型语言,失去了运行时解释的功能。

Lua的解释执行怎么就行呢?

  如果Lua的解释执行原理和C#相同,肯定也不能在IOS平台上运行时解释执行。Lua是使用C编写的脚本语言,它在运行时读入Lua编写的代码,在解释Lua字节码(Lua自己的指令)时不是翻译为机器码,而是使用C代码进行解释,不用开辟特殊的内存空间,也不会有新代码在执行,执行的是Lua的虚拟机,用C写出来的虚拟机,这和C#的机制是完全不同的,因为Lua是基于C的脚本语言。

总结

  说白了,就是由于Lua这种脚本语言的特性,基于已经存在的某种语言的一种新的语言,这也是脚本语言和C#、C++这类语言的本质区别。当然,Lua虚拟机不仅可以使用C写,也可以用C#写。使用热更新也不一定非要用Lua,Python同样可以,只不过Lua短小精悍,本身代码长度就不是很大,可以从GitHub上看到。

什么是IL

        中间语言(中间代码)是一种面向语法,易于翻译成目标程序源程序的等效内部表示代码。其可理解性及易于生成目标代码的程度介于源语言和目标语言之间。常用的中间语言有逆波兰表示、四元式、三元式和树表示等。

什么是JIT编译

      运行时需要代码时,将 Microsoft 中间语言 (MSIL) 转换为机器码的编译。

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 12,912评论 0 38
  • 第一篇 语言 第0章 序言 Lua仅让你用少量的代码解决关键问题。 Lua所提供的机制是C不擅长的:高级语言,动态...
    testfor阅读 2,135评论 1 7
  • 指令集 lua_capture_error_log lua_use_default_type lua_malloc...
    吃瓜的东阅读 11,168评论 0 2
  • 中秋佳节,最让我思念的不是月饼,而是那鲜嫩肥美的上海大闸蟹。。。 在加州,往年虽然吃不到大闸蟹,鲜美的珍宝蟹(Du...
    漾漾美味阅读 826评论 3 2
  • 你说, 我现在的想法就是你以前的想法。 我没有告诉你的是,我只是假设性的说出社会普遍的想法。这些想法,是与个人...
    栀子1202阅读 128评论 1 2