xlua unity 开发_xlua 代码分析

五一开始了,正好趁这段时间,挺闲的。整理一下xlua的原理,之前一直在lua来做热更新,觉得始终是一个API的搬运工,没有深入的了解过基础的原理。准备今天深入代码层面研究一下,而不是停留在怎么用,而是深入研究为什么会这样。

首先,先介绍一下xlua吧,用Unity开发的人对他应该挺熟悉的。对于热更新方案,现在主流方案主要是各种lua方案(tolua, xlua 等等),还有就是ILRuntime,基本就这两种吧。这里就挑选我们项目中的用到的xlua简单介绍一下,不敢说深入,怕水平不够,如果发现有什么我理解错误的地方,欢迎文章下面评论指正,不胜感激,共同进步。

下面,开始介绍吧。

xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。

xLua的突破

xLua在功能、性能、易用性都有不少突破,这几方面分别最具代表性的是:

  • 可以运行时把C#实现(方法,操作符,属性,事件等等)替换成lua实现;
  • 出色的GC优化,自定义struct,枚举在Lua和C#间传递无C# gc alloc;
  • 编辑器下无需生成代码,开发更轻量;

上面这些说明来自xlua的github上面的介绍,好像有点泛泛。

快十天过去了,终于想到过来补充完这篇文章,总不能半途而废。

再看这边问问文章之前,你必须有一些基础的知识,我现在列举了两个文章,最好先看一下,

TC130:Lua和C的互交互​zhuanlan.zhihu.com
v2-16874cc44e22dcc3ecd474e91ad889f4_180x120.jpg

上面这篇文章,主要介绍了Lua和C的交互,谢谢这位的介绍,感觉补充了很多知识盲区,Lua并不是我想起来的那么简单。如果你想看懂xLua源码的话,必须要熟悉Lua和C语言之间的交付,因为C#都是通过调用C语言库来实现和Lua之间的交付的。

先介绍一下xLua项目的一些结构,主要介绍一下,我看源码过程中比较重要的几个文件夹。

一个比较重要的文件夹

v2-d8ee9dff91960c5d575fc78a6fcb4cf4_b.jpg

这个文件夹中除了一些编译库文件需要的文件之外,有一个非常重要文件,xlua.c 主要是这个文件承担了C#和Lua之间的交互。要看实现的话,可以看一下这个文件。

v2-78a23c344a4560e9adce6dd7d693e846_b.jpg

这个文件夹中主要是一些辅助的功能,后面介绍到的Hotfix实现,需要这里面的这个工程来辅实现。看文件夹的名字好像还有一个帮助检查Lua内存泄漏的东东,这个东东这篇文章不做深入介绍(ps.其实我自己也没有看过,找个时间过来看一看)。

接下来介绍一下C#中,一些前期比较重要的一些东西。Asset下面的LuaEnv中,隐藏这一个终局大Boss。他既然是一个string变量,藏的好深。

private 

这个变量太重要了,我认为它是这个项目的核心部分,藏在了这么不起眼的地方。

下面开始讲一下我理解的Lua调用C#流程,中间省略不说调用C语言库。

比如下面的这样一条语句,是怎么调用到C#的。

CS.UnityEngine

先来看一下C#中LuaEnv这个脚本,

LuaAPI

Lua里面的print方法就是通过这几行代码实现的,你会发现最终Lua里面的print调用的是引擎里面的一个最普通的Debug.Log();

然后是通过AddSearcher方法注册一些搜索Lua脚本的方法,一般我们用的时候需要自定义扩展一个。

 DoString(init_xlua, "Init");

通过这行代码来Load init_xlua这个字符串中的Lua代码。

你会发现定义了一个叫CS的全局表,现在你们知道为什么Lua调用C#的时候需要以CS开头了吧。

接下来我们关注一下,这个CS表的元表,

function 

它是通过import_type这个方法来实现新值的载入,接下来我们来看看这个import_type方法具体是怎么实现的。

在ObjectTranslator.cs中,我截一段代码

v2-24010328e3da0b6eccc58b2a3b3512eb_b.jpg

我们来看看这个函数的实现。

        [MonoPInvokeCallback(typeof(LuaCSFunction))]
        

最后会走到这个接口中

public 

我们走到运用反射的接口看看实际的情况。

这个接口主要创建了两个元表,这个其中涉及了Lua中的注册表和upvalue的概念,不太清楚的同学,拿一本教材重新复习一下。

里面的obj meta用来管理类的成员方法和成员变量,cls meta主要是用来管理静态方法和静态变量。

接下来我们看一下,SetCSTable这个方法:

public 

下面的代码简单来说就是用前面代码生成的table表设置到CS.UnityEngine[Debug]中,最后的方法调用,应用反射的情况下,

internal 
public 

我们来看看c语言中的实现,打开xlua.c

LUA_API 

你会发现这里发现了一个闭包方法,带一个特定的upvalue,后面会通过这个upvalue来调用特定的方法。

注册代码的看起来比较简单,我这里不做介绍了。

好长的文章,终于结束了!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值