lua と C 言語の間の多くの相互変調が lua-nginx-module に表示されます。ここでは、「Lua プログラミング」の第 24 章から第 27 章にあるテスト コードをいくつか紹介します。
#include <stdio.h> #include <string.h> #include <math.h> #include <lua.h> #include <lauxlib.h> #include <lualib.h> #include <stdarg.h> #include <stdlib.h> #define MAX_COLOR 255 static void stackDump(lua_State *L); static int l_split(lua_State *L) { const char *s = luaL_checkstring(L, 1); const char *sep = luaL_checkstring(L, 2); const char *e; int i = 1; lua_newtable(L); while ((e = strchr(s, *sep)) != NULL) { lua_pushlstring(L, s, e-s); lua_rawseti(L, -2, i ++); s = e + 1; } lua_pushstring(L, s); lua_rawseti(L, -2, i); return 1; } int l_map(lua_State *L) { int i, n; luaL_checktype(L, 1, LUA_TTABLE); luaL_checktype(L, 2, LUA_TFUNCTION); n = lua_objlen(L, 1); for (i = 1; i <= n; i ++) { //stackDump(L); //printf("=====1=====\n"); lua_pushvalue(L, 2); //stackDump(L); //printf("=====2=====\n"); lua_rawgeti(L, 1, i); //stackDump(L); //printf("=====3=====\n"); lua_call(L, 1, 1); //stackDump(L); //printf("=====4=====\n"); lua_rawseti(L, 1, i); //stackDump(L); //printf("=====5=====\n"); } return 0; } // 通过Lua调用的c函数,通过打印栈说明每个函数有独立的栈 // 将c函数注册到lua中,从而被lua调用。 static int l_sin(lua_State *L) { double d = lua_tonumber(L, 1); lua_pushnumber(L, sin(d)); // stackDump(L); // printf("====l_sin===\n"); return 1; } // c 调用lua 函数 // 从Lua中得到函数,在c语言中传入参数。 double f(lua_State *L,double x, double y) { double z; lua_getglobal(L, "f"); lua_pushnumber(L, x); lua_pushnumber(L, y); // table function 1.1 2.2 说明c语言调用Lua会共享相同的栈. // stackDump(L); // printf("=====f=====\n"); if (lua_pcall(L, 2, 1, 0) != 0) printf("call f error\n"); if (!lua_isnumber(L, -1)) printf("function f must return a number\n"); z = lua_tonumber(L, -1); lua_pop(L, 1); return z; } int getfield(lua_State *L, const char *key) { int result; // stackDump(L); // printf("==1==\n"); lua_getfield(L, -1, key); // stackDump(L); // printf("==2==\n"); if (!lua_isnumber(L, -1)) printf("invalid component\n"); result = lua_tonumber(L, -1); lua_pop(L, 1); // stackDump(L); // printf("==4==\n"); return result; } static void stackDump(lua_State *L) { int i; int top = lua_gettop(L); for (i = 1; i <= top; ++ i) { int t = lua_type(L, i); switch(t) { case LUA_TSTRING: printf("'%s'", lua_tostring(L, i)); break; case LUA_TBOOLEAN: printf(lua_toboolean(L, i) ? "true" : "false"); break; case LUA_TNUMBER: printf("%g", lua_tonumber(L, i)); break; default: printf("%s", lua_typename(L, t)); break; } printf(" "); } printf("\n"); } void load(lua_State *L, const char *fname, int *w, int *h) { if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0)) printf("cannot run config.file\n"); /*lua_getglobal(L, "height"); lua_getglobal(L, "width"); if (!lua_isnumber(L, -2)) printf("width should be a number\n"); if (!lua_isnumber(L, -1)) printf("height should be a number\n"); *w = lua_tointeger(L, -2); *h = lua_tointeger(L, -1);*/ lua_getglobal(L, "table"); if (!lua_istable(L, -1)) printf("background should be table\n"); printf("%f\n", f(L, 1.1, 2.2)); float red = getfield(L, "r"); float green = getfield(L, "g"); float blue = getfield(L, "b"); printf("%f, %f, %f\n", red, green, blue); } // lua 调用c代码可以模仿这里的格式 const char* testfunc = "t = mysplit(\"hi, hello\", \",\"); print(t[1], t[2])"; int main(void) { char buff[256]; int error; lua_State *L = luaL_newstate(); luaL_openlibs(L); int w, h; // load(L, "test.lua", &w, &h); lua_pushcfunction(L, l_sin); lua_setglobal(L, "mysin"); lua_pushcfunction(L, l_map); lua_setglobal(L, "mymap"); lua_pushcfunction(L, l_split); lua_setglobal(L, "mysplit"); if (luaL_dostring(L, testfunc)) fprintf(stderr, "%s", lua_tostring(L, -1)); /* while (fgets(buff, sizeof(buff), stdin) != NULL) { error = luaL_loadbuffer(L, buff, strlen(buff), "line"); stackDump(L); error = error || lua_pcall(L, 0, 0, 0); stackDump(L); } if (error) { fprintf(stderr, "%s", lua_tostring(L, -1)); lua_pop(L, 1); }*/ lua_close(L); return 0; }
test.lua
BULE = {r = 0, g = 0, b = 1} table = {["r"] = 10, ["g"] = 23, ["b"] = 33} function f(x, y) return x + y end
以上、LuaとC言語の相互呼び出しについて内容も含めて紹介しましたが、PHPチュートリアルに興味のある方の参考になれば幸いです。