lua 和 C 語言進行互動 —— 如何傳遞table
阿新 • • 發佈:2019-02-03
方法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.lua function 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() end end
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:環境需要裝luajit3. 下面執行編譯出來的可執行檔案 exe:
key: 1
val: value1
key: 2
val: value2
key: 3
val: value3
key: 4
val: value4
key: 5
val: value5
方法2:
上面對 table 的 kv 對是這樣處理的:其實有一種效率高的方法,like this:lua_pushnumber(L, i+1); //key lua_pushstring(L, value); //value lua_settable(L, -3); //push key,value
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.lua
local 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()
end
end
domain(5)
3. 執行 lua 程式碼:
# lua test.lua
key: 1
val: value1
key: 2
val: value2
key: 3
val: value3
key: 4
val: value4
key: 5
val: 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