XLua代码
1.LuaEnv
正常的一个类的函数
public class Calc
{
intAdd(inta,intb)
{
returna+b
}}
加上热更新标签HotFix后
public class Calc
{
staticFunc<object,int,int,int>hotfix_Add=null;
intAdd(inta,intb)
{
if(hotfix_Add!=null)
return hotfix_Add(this,a,b);
returna+b
}}
1.hotfix标签的开销
2.module和require机制
Require机制:
require会先检查自己的要加载的模块是否已经被加载,如果被夹在就直接使用已经加载的模块,如果没加载则会重新加载它并初始化,热更新的核心机制就是,比如所有的逻辑代码加载都在main.lua中,收到热更新代码的信号后,重新加载main.lua文件,然后对文件进行重新加载
3.可能会有GC的地方
4.亲手实现热更新
Lua和C#互相调用
(1)C#调用Lua
public delegate double LuaMax(double a, double b);
var max = luaenv.Global.GetInPath<LuaMax>("math.max");
Debug.Log("max:" + max(20, 30));
(2)Lua调用C#
XLua.LuaEnv luaenv = new XLua.LuaEnv();
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
luaenv.Dispose();
核心:DoString函数,参数(string)
5.XLua中C#和Lua交互的机制研究
(1)调用原理
调用主要发生在栈上,核心原理就是,C#和Lua将函数,参数,返回值,error信息等放到栈上,按照约定的方式获得A语言传入的数据然后解析,然后将数据传入到B语言上的函数内,再将运算结果和执行信息(错误error,异常信息等)返回到栈上,A语言取到栈上的数据。
栈:
1.正数索引栈底为1,栈顶最大,负数索引栈顶为-1,栈底最小为-n,负数索引更加常用,毕竟常用到的信息就是位于栈顶的几位,直接通过负数索引操作数据而不用计算栈的总长度
接口:(基本上都是要传入指针)
1.rawL = LuaAPI.luaL_newstate(); // 创建一个Lua_state,并且返回一个指向堆栈的指针
2.int oldTop = LuaAPI.lua_gettop(_L); // 获取栈的长度并返回
3.LuaAPI.lua_settop(L, oldTop); // 重新设置栈的长度,lua_settop将栈顶设置为一个指定的位置,即修改栈中元素的数量。如果值比原栈顶高,则高的部分nil补足,如果值比原栈低,则原栈高出的部分舍弃,如果set为0那么意味着清空栈
4.LuaAPI.lua_pushvalue(L, idx); // 将idx处的数据压入栈顶
5.LuaAPI.lua_remove(L, idx); // 移除栈索引idx处的数据
6.lua_insert(IntPtr L, idx); // 弹出栈顶元素并插入到idx位置
7.lua_replace(IntPtr L, int idx); // 弹出栈顶元素,并且替换索引idx 处的值
8.lua_pcall(IntPtr L, int nArgs, int nResults, int errfunc); // 指针,参数个数,返回值个数,错误码(一般为0表示执行成功)
链接库:
静态链接库:无论需不需要用到,lib都会被包含在exe文件中
动态链接库:动态的对需要使用的链接库进行加载和卸载,比较灵活
Xlua:比较基础的函数接口被封装在LuaDLL中,源码大概率是用C++编写的,然后将上面的接口函数暴露在我们的XLua工程中,用C#编写的一套lua虚拟机层,给我们的游戏应用层代码C#调用
交互原则:
所有Lua中的值都由Lua来管理,C#需要什么的时候由Lua来创建,然后放到栈上,由Lua来管理其生命周期,同样C#中的值也完全由C#来管理,两种语言的变量管理是独立的,
(2)类型转换
交互一般是静态语言和动态语言的交互,比如C#,C++是静态语言,即编译时就可以确定类型,动态语言如Lua,运行时才能确定类型,那么如何匹配两种语言的类型呢,常规的类型int,string等,复杂点的委托,函数等,甚至还有interface等
映射关系:
delegate -—— function:public delegate double LuaMax(double a, double b), var max = luaenv.Global.GetInPath<LuaMax>("math.max");
class,struct —— table: 可以在lua端建一个表,将C#端连接过来的函数都加入这个表中;CS.UGUIManager.Open("UITest");
常规数据类型: