上代码,码农都喜欢上代码:
下面是main.c:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include "lua.h" #include "lualib.h" #include "lauxlib.h" void init_lua(lua_State* L) { luaL_openlibs(L); luaopen_base(L); luaopen_table(L); luaopen_string(L); luaopen_math(L); } int c_add(lua_State* L) { int a = lua_tonumber(L, -2); int b = lua_tonumber(L, -1); int c = a + b; lua_pushnumber(L, c); return 1; } int c_step(lua_State* L) { int a = lua_tonumber(L, -1); int c = a + 1; lua_pushnumber(L, c); return 1; } luaL_Reg mylib[] = { {"c_add", c_add}, {"c_step", c_step}, {NULL, NULL} }; int main() { lua_State *L = lua_open(); init_lua(L); if (luaL_loadfile(L, "test.lua") != 0) { printf("fail to load\n"); return 0; } //everything in lua is variable (including functions), so we need to init them. if (lua_pcall(L, 0, 0, 0) != 0) { printf("fail to run lua: %s\n", lua_tostring(L, -1)); return 0; } //prepare additional functions for lua to call luaL_register(L, "mylib", mylib); //c call lua lua_getglobal(L, "l_ff"); lua_pushnumber(L, 2); lua_pushnumber(L, 3); if (lua_pcall(L, 2, 1, 0) != 0) { printf("fail to call func: %s\n", lua_tostring(L, -1)); return 0; } int res = lua_tonumber(L, -1); lua_pop(L, 1); printf("in c: %d\n", res); lua_close(L); return 0; }
下面是test.lua:
function l_ff(a, b) local c = mylib.c_add(a, b) + 1 print ("in lua1: ", c) local d = mylib.c_step(c) print ("in lua2: ", d) return d end
说明
这些api的名字很怪异,常常没法从名字知道这个函数是做什么的。
lua_getglobal是从lua脚本里面取一个全局变量放到堆栈上(c和lua之间是通过虚拟的堆栈来互相沟通的)。
lua_pushnumber是把一个数字放到堆栈上。
lua_pcall是从当前堆栈进行函数调用。
lua_tonumber这个是把堆栈中的某个值作为int取出来(因为l_ff有返回值,因此堆栈最顶上就是函数的返回值)
在函数c_add里面,lua_pushnumber才是lua调用的返回值(在lua里面,同样是把把栈最顶上的位置当作返回值)