「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」。
作为一名优秀的开发者,对于技术的探求应该是永无止步的,如何让自己更进步,那就只有不停的学习,不停的充电.而这些都都是说起来容易做起来难,坚持才是难的地方 --蛙哈哈
XLua实现原理-02
1.先来一个简单示例
public class Helloworld : MonoBehaviour
{
// Use this for initialization
void Start()
{
LuaEnv luaenv = new LuaEnv();
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
luaenv.Dispose();
}
}
LuaEnv luaenv = new LuaEnv();
先创建一个Lua虚拟机.
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
再用虚拟机执行Lua代码
2.Lua和C#是怎么交互的
首先我们要知道的是,lua本身提供了C_API,让我们push一个值到lua虚拟栈上。lua可以通过访问lua虚拟栈,
来访问这个对象。
Lua虚拟栈是lua和其他语言交换数据的中介。
由于C和lua中的数据结构是完全不一样的,并且lua函数可以返回多个结果,所以要有一种在lua脚本和C函数
之间交换数据的机制,这个机制就是虚拟栈.
这个栈可以储存任何类型的数据,供lua调用的C函数从这个栈中获取调用参数,然后将结果再压入栈中返回到
lua,这个虚拟栈用索引来操作.
xlua对以上接口进行了封装,并同样提供了一系列的push方法,让我们可以把一个c#对象push到lua的虚拟栈上。
可以把xlua的push API归为两类:一类是针对某种特定类型的push,暂且叫做LowLevelAPI;
还有一类是基于LowLevelAPI封装的更上层的HighLevelAPI。
传递基元类型
编译器直接支持的数据类型称为基元类型(primitive type)。基元类型直接映射到Framework类库(FCL)中存在的类型。
FCL类型在C#中对应的基元类型:
Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、IntPtr、UIntPtr、Char、Double和 Single。
从某个角度来说,可以认为C#编译器自动为所有源代码文件添加using指令为类型创建别名。
using int = System.Int32;
为什么我们传给lua的对象是一个int类型(这里的key)?
其实我们这里的key是我们要传递的c#对象的一个索引,我们可以通过这个索引找到这个c#对象
当传递一个c#对象的时候,我们创建一个userdate,并把这个索引值赋给这个userdata。
然后,lua在全局注册表中,有一张专门的表用来存放c#各种类型所对应的元表,
而meta_ref就是当前这个对象所对应类型的元表的索引id,
我们通过他找到对应的元表,就可以通过setmetatable来绑定操作这个对象的方法。
最终lua就可以愉快的使用这个对象。