Skip to content
Ein Verne edited this page Sep 25, 2016 · 1 revision

在 C++ 中跑 Lua 文件脚本,Game Dev Geek 已经有了很多篇教程,从入门的环境配置,到从 C++ 中传参给 Lua,并调用 Lua 中的函数,获取返回值的教程,甚至是从 Lua 中调用 C++ 的教程 。这几篇文章写得都比较全面,并且几乎三大平台都有涉及。

但是缺点都,这三篇文章都是基本入门的参考,项目中因为 Lua 脚本都存在数据库中,读取之后 Lua 脚本存在于内存当中,需要用到 luaL_loadbuffer 方法,这三篇文章中都没有提到。

int luaL_loadbuffer (lua_State *L,
                     const char *buff,
                     size_t sz,
                     const char *name);

将内存中的Lua脚本加载作为 Lua chunk ,背后使用 luaL_loadbufferx 其中mode 参数为 NULL, 参数解释

  • L Lua 状态
  • buff 待运行Lua脚本
  • sz 该脚本的长度,一般使用 strlen() 来获取
  • name 加载之后作为 chunk 的名字

更加具体的代码可参考:

#include <stdio.h>
#include <string.h>
extern "C" {
      #include "lua.h"
      #include "lualib.h"
      #include "lauxlib.h"
}
int main(void)
{
    const char* buff = "print(\"hello\")";
    int error;
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);

    error = luaL_loadbuffer(L,buff,strlen(buff),"line") || lua_pcall(L,0,0,0);
    int s = lua_gettop(L);
    if (error) {
        fprintf(stderr,"%s",lua_tostring(L,-1));
        lua_pop(L,1);
    }
    lua_close(L);
    return 0;
}

下面是针对以上代码给出的具体解释:

  • 1). 使用 extern include 头文件 lua.h。
    
  • 2). Lua库中没有全局变量,将所有的状态都保存在动态结构lua_State中,后面所有的C API都需要该指针作为第一个参数。
    
  • 3). luaL_openlibs 函数是用于打开Lua中的所有标准库,如io库、string库等。
    
  • 4). luaL_loadbuffer 编译了buff中的Lua代码,如果没有错误,则返回0,同时将编译后的程序块压入虚拟栈中。
    
  • 5). lua_pcall 函数会将程序块从栈中弹出,并在保护模式下运行该程序块。执行成功返回0,否则将错误信息压入栈中。
    
  • 6). lua_tostring 函数中的-1,表示栈顶的索引值,栈底的索引值为1,以此类推。该函数将返回栈顶的错误信息,但是不会将其从栈中弹出。
    
  • 7). lua_pop 是一个宏,用于从虚拟栈中弹出指定数量的元素,这里的1表示仅弹出栈顶的元素。
    
  • 8). lua_close 用于释放状态指针所引用的资源。