首頁  >  文章  >  後端開發  >  lua與c語言互相調用

lua與c語言互相調用

WBOY
WBOY原創
2016-08-08 09:23:391869瀏覽

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

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

以上就介紹了lua與c語言互相調用,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn