【Lua与C#交互①】Lua中的栈

Lua是用C写的编程语言,它提供了一系列的API供用户可以在C里面调用,详见参考手册
在这里插入图片描述
在unity使用的xlua或者tolua等lua都是对Lua进行了封装,帮我们搭好C#到Lua这个桥梁。之所以要学习Lua和C#交互,是为了让我们更好的掌握Lua,从而不停留在只会用轮子的阶段。这篇文章是系列第一篇,所以会讲解一个最简单的例子。


首先,Lua和C++/C/C#交互的时候内部会维护一个堆栈
请大家注意图上标记的索引,Lua通过索引来拿到栈里面的数据,这些数据包括functiontable数值stringbool等。

  • 1代表栈底,往上递增
  • -1代表栈顶,往下递减
    在这里插入图片描述
    OK,那么接下来我们来写代码。首先将xLua或者toLua或者其它lua导入到unity工程。我这边使用的是xLua,其它Lua也会有类似的接口可以调用。
    先上完整代码,结果是控制台会打印 756915370 这段数字。
using UnityEngine;
using System.Collections;
using System;
using LuaAPI = XLua.LuaDLL.Lua;

public class Test : MonoBehaviour
{
    
    
    IntPtr L;

    double num = 756915370;

    // Use this for initialization
    void Start()
    {
    
    
        L = LuaAPI.luaL_newstate();
        LuaAPI.lua_pushnumber(L, num);
        if(LuaAPI.lua_isnumber(L, 1))
        {
    
    
            Debug.Log(LuaAPI.lua_tonumber(L, 1));
        }
        LuaAPI.lua_close(L);
    }

让我们一行行来看。

L = LuaAPI.luaL_newstate();

luaState的概念

luaState 中放的是 lua 虚拟机中的环境表、注册表、运行堆栈、虚拟机的上下文等数据。可以理解为我们写代码常用的各种manager类。在xLua中luaState被封装成了LuaEnv类,在toLua中叫作LuaState

Intptr是C#的指针。返回一个Intptr的目的是为了让C#能够持有luaState的引用。关于Intptr可以看MSDN,或者看这篇文章


下一行:

 LuaAPI.lua_pushnumber(L, num);

对lua堆栈的操作

这一行没什么好说的,就是往栈顶添加数据。类似的函数还有lua_pushstringlua_pushboolean等,不过table的话是使用lua_createtable


下一行:

  if(LuaAPI.lua_isnumber(L, 1))
  {
    
    
      Debug.Log(LuaAPI.lua_tonumber(L, 1));
  }

根据索引找到数据

这个就用到了之前说的,1代表栈底,因为我们只有一个数据,显然栈底就是我们想要的。先判断1这个位置的数据是不是数值,然后打印。


最后:

LuaAPI.lua_close(L);

内存回收

最后一行代码就是取消对luaState的引用,以便下次GC能够回收这块内存。
说到内存,我顺带写一下今天看xLua源码学到的知识。

关于IDisposable和Dispose()
  • 实现了IDisposable的类,在GC时会调用Dispose方法。
  • Dispose方法是在另一个线程里跑的,所有实现了IDisposable的类所占用的内存在GC后不会立刻回收,而是等全部Dispose方法调用完之后回收。
  • 如果主线程想等Dispose的线程跑完之后再做一些事情,使用System.GC.WaitForPendingFinalizers()
  • Dispose() 里面的代码需要考虑是否被多次调用,如果你在其它地方也调用类的Dispose() 的话,比如 OnDestroy() 等等。

2020.4.29:
更新适用于tolua版本的代码

 var num = 756915370;
 IntPtr L = LuaDLL.luaL_newstate();
 LuaDLL.lua_pushnumber(L,num);
 //等于1说明是True
 if (LuaDLL.lua_isnumber(L, 1) == 1)
 {
    
    
     Debug.Log(LuaDLL.lua_tonumber(L,1));
 }
 LuaDLL.lua_close(L);

2020.6.20:
将tolua删掉,替换成自己打包的lua。
LuaState和luaDLL由自己实现。


github工程
对应的文件夹是Examples/01_Stack

系列文章:
【Lua与C#交互①】Lua中的栈
【Lua与C#交互②】加载Lua文件
【Lua与C#交互③】方法调用和错误处理函数

qq群:891809847

猜你喜欢

转载自blog.csdn.net/j756915370/article/details/105779176
今日推荐