lua与c语言互相调用

来源:互联网 发布:深圳it培训机构 编辑:程序博客网 时间:2024/05/19 18:44

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 255static 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 + yend

编译:gcc test.c -I/usr/local/include/luajit-2.0 -llua-5.1 -lm


0 0
原创粉丝点击