c++与lua的实战二

一、简单参数的传递

c++获取lua中的参数

// first.cpp : Defines the entry point for the console application.
//
extern "C"{
#include<lua.h>
#include<lauxlib.h>
#include<lualib.h>
}
int CTest(lua_State *L){
	printf("int CTest");
	size_t len;
	const char *name = lua_tolstring(L, 1, &len);
	
	int age = lua_tonumber(L,2);
	
	bool is = lua_toboolean(L,3);
	printf("Lua name = %s  age=%d is=%d\n ",name,age,is);
	return 0;
}



int main(int argc, char* argv[])
{
	
		lua_State *L = lua_open();
		luaopen_base(L);
		luaopen_string(L);
		luaopen_table(L);
		lua_register(L, "CTest", CTest);
		//打开基本库
		if (luaL_loadfile(L, "main.lua"))
		{
			const char *error = lua_tostring(L, -1);
			printf("Lua load error %s", error);
			return -1;
		}
		if (lua_pcall(L, 0, 0, 0))
		{
			const char *error1 = lua_tostring(L, -1);
			printf("Lua load error %s", error1);
			return -1;
		}//依次是参数个数、返回值、错误个数
		getchar(); 

	return 0;
}
main.lua代码
CTest("lua string",789,false)

二、索引数组参数的传递

int CTestArr(lua_State *L){
	printf("In CTestArr");
	int len = luaL_getn(L,1);
	for (int i = 1; i <= len ; i++){
		lua_pushnumber(L,i) ;
		lua_gettable(L, 1);//lua_gettable函数会从栈顶取得一个值,然后根据这个值去table中寻找对应的值,最后把找到的值放到栈顶。
		size_t size;
		printf("%s\n", lua_tolstring(L, -1, &size));
		lua_pop(L, 1);//这个1表示的是个数
	}
	return 0; 
}


int main(int argc, char* argv[])
{
	
		lua_State *L = lua_open();
		luaopen_base(L);
		luaopen_string(L);
		luaopen_table(L);
		lua_register(L, "CTest", CTest);
		lua_register(L, "CTestArr", CTestArr);
		//打开基本库
		if (luaL_loadfile(L, "main.lua"))
		{
			const char *error = lua_tostring(L, -1);
			printf("Lua load error %s", error);
			return -1;
		}
		if (lua_pcall(L, 0, 0 , 0))
		{
			const char *error1 = lua_tostring(L, -1);
			printf("Lua load error %s", error1);
			return -1;
		}//依次是参数个数、返回值、错误个数
		getchar(); 

	return 0;
}

local arr={"A001","A002","A003","A004"}

非数组表(key,value)的参数传递

lua_next(L,3)
1.先从栈顶 弹出一个key
2.从栈指定位置的table里取下一对key-value,先将key入栈再将value入栈
3.如果第二步成功则返回非0值,否则返回0,并且不想栈中国压入任何值

int CTestTable(lua_State *L){
	lua_pushnil(L);
	while (lua_next(L, 1) != 0) //从栈底取出一对key、value成功的话返回非零,失败返回零
	{							//再将其放入栈顶
		printf("key = %s ",lua_tostring(L, -2));
		printf("value =%s\n",lua_tostring(L, -1));
		lua_pop(L, 1);
	}
	return 0;
}
int main(int argc, char* argv[])
{
	
		lua_State *L = lua_open();
		luaopen_base(L);
		luaopen_string(L);
		luaopen_table(L);
		lua_register(L, "CTest", CTest);
		lua_register(L, "CTestArr", CTestArr);
		lua_register(L, "CTestTable", CTestTable);
}

c++获取lua表的内容

int CTestTable1(lua_State *L)
{
	lua_getfield(L, 1 ,"name");  //1是指栈底第一个元素在底部 
	printf("name = %s\n",lua_tostring(L,-1));
	return 0;
}

参数类型检查

int CTestTable2(lua_State *L){
	luaL_checktype(L, 1, LUA_TTABLE); //第二个参数是表类型。可能会因为参数类型不对而报错
	if (lua_type(L ,  2) != LUA_TNUMBER) //这个表示参数位置
	{
		printf("para 2 is not number\n");
	}
	lua_getfield(L, 1,"name");
	printf("name = %s\n", lua_tostring(L, -1));
	return 0 ;
}

由c++向lua中传递string参数

int CTestRe(lua_State *L){

	lua_pushstring(L, "return value");
	return 1; // 栈顶元素弹出的个数 
}

lua代码

local re= CTestRe()
 print("re =:"..re)

由c++向lua中传递表参数

c++代码

int CTestTable3(lua_State *L)
{
	lua_newtable(L);

	lua_pushstring(L, "name");
	lua_pushstring(L, "xiaoming");
	lua_settable(L, -3);
	//会把刚刚插入的key和value出栈
	lua_pushstring(L, "age");
	lua_pushnumber(L, 21);
	lua_settable(L, -3);
	return 1;
}

lua代码

local re = CTestTable3()
print("name = :"..re["name"])
print("age = :" ..re["age"])

c++调用lua中的全局变量(普通)lua->c++

注意:此处代码需要放在pcall后面

lua_getglobal(L, "width");//获取并放到栈顶
		int width = lua_tonumber(L, -1);
		lua_pop(L, 1);
		printf("width = %d \n", width);
		lua_close(L);

在lua代码中只需要有个变量就行

c+±>lua全局变量传递(普通)

lua_pushstring(L, "hello");
lua_setglobal(L, "test");//将栈顶位置设置全局变量并出栈 

print("c++ :test",test)

lua->c++ 全局变量(表)

lua_getglobal(L, "conf");
		lua_getfield(L, -1, "titlename");
		printf("title =%s\n", lua_tostring(L, -1));
		lua_pop(L, 1);
		lua_getfield(L, -1, "height");
		printf("height =%d\n", (int)lua_tonumber(L, -1));
		lua_pop(L,1);// 3是总和  

c++给Lua传递表(全局)在这里插入图片描述

lua_newtable(L);
		lua_pushstring(L, "name");
		lua_pushstring(L, "xiaoming");
		lua_settable(L, -3);

		lua_pushstring(L, "age");
		lua_pushnumber(L, 20);
		lua_settable(L, -3);

		lua_setglobal(L, "person");

lua代码



print("person name is :"..person["name"]);
print("person age is :"..person.age);

c++调用Lua函数

注意:保证在一个线程中,可以改写锁,建立lua状态(更推荐)


		lua_getglobal(L, "event");
		lua_pcall(L,0,0,0); //发生错误会压到栈顶,如果传了则不会

堆栈优化后

printf("top is %d\n", lua_gettop(L));
		lua_getglobal(L, "event");
		if(lua_pcall(L,0,0,0)!=0) //发生错误会压到栈顶,如果传了则不会
		{
			printf("call event failed %s\n", lua_tostring(L,-1));
			lua_pop(L, 1);
		}
		printf("top is %d\n", lua_gettop(L));

lua代码

function event()
	print("c++ call lua function");
end

向lua传参数

printf("top is %d\n", lua_gettop(L));
		lua_getglobal(L, "event");
		lua_pushstring(L, "key");
		if(lua_pcall(L,1,0,0)!=0) //发生错误会压到栈顶,如果传了则不会
		{
			printf("call event failed %s\n", lua_tostring(L,-1));
			lua_pop(L, 1);
		}
		printf("top is %d\n", lua_gettop(L));

lua代码

function event(e)
	print("c++ call lua function");
	print(e);
end

打印lua返回值

printf("top is %d\n", lua_gettop(L));
		lua_getglobal(L, "event");
		lua_pushstring(L, "key");
		if(lua_pcall(L,1,1,0)!=0) //发生错误会压到栈顶,如果传了则不会
		{
			printf("call event failed %s\n", lua_tostring(L,-1));
			lua_pop(L, 1);
		}
		else
		{
			printf("返回值是%s", lua_tostring(L, -1));
		}
		printf("top is %d\n", lua_gettop(L));

lua代码

function event(e)
	print("c++ call lua function");
	print(e);
	return "it's me"
end

调用lua参数的错误处理

printf("top is %d\n", lua_gettop(L));
		int errfun = lua_gettop(L);
		lua_getglobal(L, "ferror");
		errfun++;                       //加参数从栈的底部数是固定的
		lua_getglobal(L, "event");
		lua_pushstring(L, "key");
		if(lua_pcall(L,1, 1,errfun)!=0) //发生错误会压到栈顶,如果传了则不会
		{										//在发生运行时错误时, 这个函数会被调用而参数就是错误消息。 错误处理函数的返回值将被 lua_pcall 作为错误消息返回在堆栈上。
			printf("call event failed %s\n", lua_tostring(L,-1));
			lua_pop(L, 1); 
		}
		else
		{
			printf("返回值是%s", lua_tostring(L, -1));
			lua_pop(L, 1);
		}
		lua_pop(L,1);
		printf("top is %d\n", lua_gettop(L)); 
		lua_close(L);

lua代码

function ferror(e)
	print("My error:"..e)
	return "lua change error";
end
function event1(e)
	print("c++ call lua function");
	print(e);
	return "lua event return"
end

注意:pcall如果没有错误函数则会将错误压到栈顶

c++调用返回参数获取返回表

printf("top is %d\n", lua_gettop(L));
		int errfun = lua_gettop(L);
		lua_getglobal(L, "ferror");
		errfun++;                       //加参数从栈的底部数是固定的
		lua_getglobal(L, "event");
		lua_pushstring(L, "key");

		lua_newtable(L);
		lua_pushstring(L, "name");
		lua_pushstring(L, "xiaoming");
		lua_settable(L, -3);  

		if(lua_pcall(L,2,1,errfun)!=0) //发生错误会压到栈顶,如果传了则不会
		{										//在发生运行时错误时, 这个函数会被调用而参数就是错误消息。 错误处理函数的返回值将被 lua_pcall 作为错误消息返回在堆栈上。
			printf("call event failed %s\n", lua_tostring(L,-1));
			lua_pop(L, 1); 
		}
		else
		{
			lua_getfield(L, -1, "id"); //调完之后会把value压到栈顶
			printf("return table :%d \n", (int)lua_tonumber(L, -1) );
			lua_pop(L, 2);
		}
		lua_pop(L,1); 
		printf("top is %d\n", lua_gettop(L)); 
		lua_close(L);

lua代码

function ferror(e)
	print("My error:"..e)
	return "lua change error";
end
function event(e,obj)
	print("c++ call lua function");
	print(e);
	print(obj.name)
	--return "lua event return"
	local re = {id=123}
	return re;
end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值