Tolua使用笔记二:lua与C#的函数,变量交互方法

原文地址:http://blog.csdn.net/qq_30168505/article/details/52744478

接着上一回的接着讲:

案例三:

到这里久终于到了大家最感兴趣的地方了,热更新的价值就在于用脚本语言写逻辑,这样可以实现逻辑的频繁改动而不用每次更新都重新下载。

而这个过程中必然涉及到C#对lua的一个逻辑调用,而这个例子实现的就是C#的函数的调用

核心代码如下:

    private string script = 
        @"  function luaFunc(num)                        
                return num + 1
            end

        test = {}
        test.luaFunc = luaFunc
    ";

LuaFunction func = null;
LuaState lua = null;

void Start () 
   {
    lua = new LuaState();
    lua.Start();
    lua.DoString(script);

    //Get the function object
    func = lua.GetFunction("test.luaFunc");

    if (func != null)
    {
        //有gc alloc
        object[] r = func.Call(123456);
        Debugger.Log(r[0]);

        // no gc alloc
        int num = CallFunc();
        Debugger.Log(num);
    }

    lua.CheckTop();
}

  int CallFunc()
    {        
        func.BeginPCall();                
        func.Push(123456);
        func.PCall();        
        int num = (int)func.CheckNumber();                    
        func.EndPCall();
        return (int)num;        
    }

效果图如下:

对于本章,主要的知识点如下:

1:对于lua的函数在C#中的调用,首先在lua中函数是一个对象(严格意义上说C#里面也算是对象吧~~),在虚拟机初始化完成后,加载了对应的lua文件之后,必须要创建一个LuaFunction类型的对象,通过调用  lua.GetFunction(“方法名”); 获取lua文件中对应的函数对象,接下来就是调用了

C#中调用lua函数的方法有2种:

1:直接调用LuaFunction类型的对象的func.Call 方法,完整声明为:public object[] Call(params object[] args)

这种调用方法比较简单,但是为一个缺点,lua对象的内存无法被自动释放,所以当使用完这个lua对象之后,我们需要手动的调用LuaFunction类型的对象的func.Dispose();方法,释放掉垃圾内存,否则会造成内存泄漏。

2:如样例中的CallFunc()所示,代码如下:

int CallFunc()
    {        
        func.BeginPCall();                
        func.Push(123456);
        func.PCall();        
        int num = (int)func.CheckNumber();                    
        func.EndPCall();
        return (int)num;        
    }
使用 方法非常麻烦,必须要先以func.BeginPCall();开使,通过func.Push(参数)来给方法传参,然后需要通过这一步 func.PCall();  来运行 , 最后通过对应的func.Check xxx()方法来获取返回值,最后还要通过func.EndPCall();结束 , 整个流程比较繁琐且不是很容易封装,不过优点是不会有垃圾内存,所以不用手动释放GC。


案例4:

这个案例主要是介绍C#中如何获取,声明,使用lua中的变量,核心代码如下:(这次好像又是难得的整篇代码都是重点)

public class AccessingLuaVariables : MonoBehaviour 
{
    private string script =
        @"
            print('Objs2Spawn is: '..Objs2Spawn)
            var2read = 42
            varTable = {1,2,3,4,5}
            varTable.default = 1
            varTable.map = {}
            varTable.map.name = 'map'

        meta = {name = 'meta'}
        setmetatable(varTable, meta)

        function TestFunc(strs)
            print('get func by variable')
        end
    ";

void Start () 
{        
    LuaState lua = new LuaState();
    lua.Start();
    lua["Objs2Spawn"] = 5;
    lua.DoString(script);

    //通过LuaState访问
    Debugger.Log("Read var from lua: {0}", lua["var2read"]);
    Debugger.Log("Read table var from lua: {0}", lua["varTable.default"]);

    LuaFunction func = lua["TestFunc"] as LuaFunction;
    func.Call();
    func.Dispose();

    //cache成LuaTable进行访问
    LuaTable table = lua.GetTable("varTable");
    Debugger.Log("Read varTable from lua, default: {0} name: {1}", table["default"], table["map.name"]);
    table["map.name"] = "new";
    Debugger.Log("Modify varTable name: {0}", table["map.name"]);

    table.AddTable("newmap");
    LuaTable table1 = (LuaTable)table["newmap"];
    table1["name"] = "table1";
    Debugger.Log("varTable.newmap name: {0}", table1["name"]);
    table1.Dispose();

    table1 = table.GetMetaTable();

    if (table1 != null)
    {
        Debugger.Log("varTable metatable name: {0}", table1["name"]);
    }

    object[] list = table.ToArray();

    for (int i = 0; i < list.Length; i++)
    {
        Debugger.Log("varTable[{0}], is {1}", i, list[i]);
    }

    table.Dispose();
    lua.CheckTop();
    lua.Dispose();
}

}

效果图如下:


这个案例中主要的知识点如下:

1:创建lua虚拟机的全局变量: 在lua虚拟机创建完成且初始化完毕(调用Start方法)之后,可以直接通过以下格式声明一个lua虚拟机的全局变量   lua[“变量名”] = 值;   则创建了一个名为   变量名   的 lua全变量,值为 右式的值
2:访问 lua的变量,和创建lua虚拟机的变量的格式相同,这一点和lua中关于变量的定义是相同的,如果有就创建,否则就获取对应的值,其中对于lua中的函数的使用是需要经过强转,例如lua中的函数 ,具体如下:

 LuaFunction func = lua[“TestFunc”] as LuaFunction;

3:lua中table的获取和创建:通过调用虚拟机的方法lua.GetTable 来获取lua中的table,用LuaTable类型来储存lua中的Table,通过调用Luatable的成员方法table.AddTable来创建lua中的table , 除了通过虚拟机的GetTable方法我访问之外,直接通过 LuaTable  型变量按字典的类似方法也可以调用tabel , 例如如下:

<span style="color:#FF0000;">LuaTable table1 = (LuaTable)table["newmap"];</span>
对于lua元表也是可以获取的,方法为调用 LuaTable的table.GetMetaTable();方法,则可以获得lua的元表Table

注意一下:对LuaTable型的变量,在使用完之后需要手动释放内存,否则会应为内存未自动释放造成内存泄露~~~具体方法为调用LuaTable对象的方法table.Dispose();

说到到这里就差不多了,后面的咱们下回分解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值