lua与c语言互相调用

php中文网
发布: 2016-08-08 09:23:39
原创
2188人浏览过

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

云雀语言模型
云雀语言模型

云雀是一款由字节跳动研发的语言模型,通过便捷的自然语言交互,能够高效的完成互动对话

云雀语言模型 54
查看详情 云雀语言模型

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教程有兴趣的朋友有所帮助。

C语言速学教程(入门到精通)
C语言速学教程(入门到精通)

C语言怎么学习?C语言怎么入门?C语言在哪学?C语言怎么学才快?不用担心,这里为大家提供了C语言速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号