上代码,码农都喜欢上代码:
下面是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里面,同样是把把栈最顶上的位置当作返回值)