上代碼,碼農都喜歡上代碼:
下面是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 callluaL_register(L, "mylib", mylib);//c call lualua_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) + 1print ("in lua1: ", c)local d = mylib.c_step(c)print ("in lua2: ", d)return dend
說明
這些api的名字很怪異,常常沒法從名字知道這個函數是做什麼的。
lua_getglobal是從lua指令碼裡面取一個全域變數放到堆棧上(c和lua之間是通過虛擬堆棧來互相溝通的)。
lua_pushnumber是把一個數字放到堆棧上。
lua_pcall是從當前堆棧進行函數調用。
lua_tonumber這個是把堆棧中的某個值作為int取出來(因為l_ff有傳回值,因此堆棧最頂上就是函數的傳回值)
在函數c_add裡面,lua_pushnumber才是lua調用的傳回值(在lua裡面,同樣是把把棧最頂上的位置當作傳回值)