lua 和 C 语言进行交互 —— 如何传递table

来源:互联网 发布:哪里可以买到淘宝店铺 编辑:程序博客网 时间:2024/06/06 03:07

方法1:

采用 lua_pushstring/lua_pushnumber 传递key、value,然后通过 lua_settable 设置 table 中的kv对,like this:
        lua_pushnumber(L, 1);        lua_pushstring(L, "value1");        lua_settable(L, -3);
其中“lua_settable(L, -3)”表示将前压栈中的前两个参数作为一个kv对放到table中。

1. 首先编写 lua 文件 lua_test.lua:

-- file: lua_test.luafunction domain(i)    -- call C function.    local tab = gettab()     -- show key and value    for k, v in pairs(tab) do        print("key: ".. k)        print("val: ".. v)print()    endend

2. 其中 gettab 是 C 中注册的函数,下面是对应的 C 代码 c_test.c :

/* * file: c_test.c */#include <lua.h>#include <lauxlib.h>#include <lualib.h>#include <string.h>#include <unistd.h>#include <stdio.h>int get_tab(lua_State *L){    /* create table. */    lua_newtable(L);    /* push (key, value). */    int i;    char value[10] = {0};    for(i=0; i<5; ++i)    {        sprintf(value, "value%d", i+1);        lua_pushnumber(L, i+1);    //key        lua_pushstring(L, value);  //value        lua_settable(L, -3);       //push key,value    }    /* deal return. */    return 1;}int main(){    /* create a state and load standard library. */    lua_State* L = luaL_newstate();    /* opens all standard Lua libraries into the given state. */    luaL_openlibs(L);    /* register function be called by lua. */    lua_register(L, "gettab", get_tab);    /* load and exec the specified lua file. */    int error = luaL_dofile(L, "lua_test.lua");    if(error) {        perror("luaL_dofile error");        exit(1);    }    /* get the domain function from lua file. */     lua_getglobal(L,"domain");    /* exec the domain function. */    error = lua_pcall(L, 0, 0, 0);    if (error) {        fprintf(stderr,"%s\n",lua_tostring(L,-1));        lua_pop(L,1);    }    /* close lua state. */    lua_close(L);    return 0;}
使用一下命令编译:
gcc c_test.c -I/usr/local/include/luajit-2.0 -L/usr/local/lib -lluajit-5.1 -o exe
note:环境需要装luajit

3. 下面执行编译出来的可执行文件 exe:

key: 1val: value1key: 2val: value2key: 3val: value3key: 4val: value4key: 5val: value5

方法2:

上面对 table 的 kv 对是这样处理的:
        lua_pushnumber(L, i+1);    //key        lua_pushstring(L, value);  //value        lua_settable(L, -3);       //push key,value
其实有一种效率高的方法,like this:
        lua_pushstring(L, value);        lua_rawseti(L, -2, i++);

最后再写一种 lua 调用函数库的方法:

1. 首先编写 C 文件 so_test.c:

/*  * file:so_test.c */#include <lua.h>#include <lauxlib.h>#include <lualib.h>#include <stdio.h>int get_tab(lua_State *L){    /* get the input. */    int num = lua_tonumber(L, 1);    /* create table. */    lua_newtable(L);    /* push (key, value). */    int i;    char value[10] = {0};    for(i=0; i<num; ++i)    {        sprintf(value, "value%d", i+1);        lua_pushnumber(L, i+1);        lua_pushstring(L, value);        lua_settable(L, -3);    }    /* deal return. */    return 1;}static const luaL_Reg mylib[] = {    {"get_tab", get_tab},    {NULL, NULL}};int luaopen_lua_test(lua_State *L) {    luaL_register(L, "lua_test", mylib);    return 0;}
用以下命令编译出动态库 lua_test.so:
gcc so_test.c -shared -fPIC -I/usr/local/include/luajit-2.0/ -I/usr/include/ -lluajit-5.1 -o lua_test.so

2. 然后编写 lua 测试代码 test.lua:

-- file: test.lualocal test = require('lua_test')function domain(num)    -- call C function.    local tab = test.get_tab(num)     -- show key and value    for k, v in pairs(tab) do        print("key: ".. k)        print("val: ".. v)print()    endenddomain(5)

3. 执行 lua 代码:

# lua test.lua key: 1val: value1key: 2val: value2key: 3val: value3key: 4val: value4key: 5val: value5

以上代码的编译执行环境:

os:CentOS release 6.4 (Final)

gcc:gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)

lua:Lua 5.1.4

luajit:LuaJIT 2.0.2

参考书:Programming in Lua
0 0