lua和C++调用学习笔记系列一

文章目录

    • 一、lua与C++如何交互
      • 1)C++和lua交互顺序
      • 2)lua堆栈展示
      • 3)lua调用C++函数代码示例
      • 4)执行结果
    • 二、lua传递参数返回给C/C++
      • 1)传递字符串类型给C/C++
      • 2)传递整数类型
      • 3)传递bool类型
    • 三、lua调用C++传递数组参数
    • 四、lua给C++函数传递表参数
      • 1)函数说明
      • 2)代码
      • 3)lua获取表中特定key对应的value内容

一、lua与C++如何交互

lua和C++调用学习笔记系列一_第1张图片

1)C++和lua交互顺序

①C++往lua堆栈里面写东西
②lua获取这些堆栈的数据后,拿到lua全局表进行操作
③lua在全局表拿到结果后,再把结果返回到lua堆栈中
④C++再去读取lua堆栈信息

2)lua堆栈展示

lua和C++调用学习笔记系列一_第2张图片

3)lua调用C++函数代码示例

(1)传递参数类型

数字、字符串、bool、用户类型

(2)获取返回值类型

数字、字符串、bool、结构体对象

  • first.cpp
#include 
#include 

//定义函数
//lua_State状态,我们通过状态来操作堆栈、调试、内存监控
int CTest(lua_State* L)
{
	printf("int CTest\n");
	return 0;//返回结果个数,
	//返回0表示没有返回值,返回一表示一个参数
}

int main(int argc,char* argv[])
{
	lua_State* lua = lua_open();
	luaopen_base(lua);
	luaopen_string(lua);
	luaopen_table(lua);
	
	//注册函数,告诉lua我写了这个函数
	lua_register(lua,"CTest",CTest);//CTest是名称,可以和函数名是不一致的,可以自己定义的	

	if(luaL_loadfile(lua,"main.lua"))
	{
		const char* error = lua_tostring(lua,-1);
		printf("lua load error:%s\n",error);
	}
}

  • main.lua
CTest()

4)执行结果

lua和C++调用学习笔记系列一_第3张图片

二、lua传递参数返回给C/C++

  • 参数传递顺序(lua的压栈是从底部位置1开始的)
    从栈底1开始,从1到4,访问第一个参数的方式就是通过访问栈底第一个参数
    lua和C++调用学习笔记系列一_第4张图片

lua和C++调用学习笔记系列一_第5张图片

1)传递字符串类型给C/C++

  • main.lua
CTest("lua string",123,true)
  • 函数
int CTest(lua_State* L)
{
	size_t len = 0;
	const char* str = lua_tolstring(L,1,&len);//返回栈顶的字符串,
	//并返回字符串的长度放到len里面
	printf("lua name = %s",str);
	return 0;
}

在这里插入图片描述

2)传递整数类型

int CTest(lua_State* L)
{
	int age = 0;
	age = lua_tonumber(L,2);
	printf("age = %d\n",age);
}

在这里插入图片描述

3)传递bool类型

int CTest(lua_State* L)
{
	bool is = lua_toboolean(L,3);
	printf("bool is = %d",is);
}

在这里插入图片描述

三、lua调用C++传递数组参数

  • main.lua
local arr = {"A001","A002","A003","A004"};
CTestArr(arr);
  • main.cpp
#include 
#include 

int CTestArr(lua_State* L)
{
	printf("In CTestArr\n");
	int arr_len = luaL_getn(L,1);//获取lua栈底表的大小
	for(int i = 0; i < len; ++i)
	{
		lua_pushnumber(L,i);//往栈顶压入整数
		lua_gettable(L,1);//栈顶元素出栈,并放到表的i的位置
		size_t size;
		printf("%s\n",lua_tolstring(L,-1,&size));//打印栈顶元素
		lua_pop(L,1);    //栈顶元素出栈
	}
	return 0;
}

int main(int argc,char* argv[])
{
	lua_State* lua = lua_open();
	luaopen_base(lua);
	luaopen_string(lua);
	luaopen_table(lua);
	
	//注册函数,告诉lua我写了这个函数
	lua_register(lua,"CTest",CTest);//CTest是名称,可以和函数名是不一致的,可以自己定义的	
	lua_register(lua,"CTestArr",CTestArr);

	if(luaL_loadfile(lua,"main.lua"))
	{
		const char* error = lua_tostring(lua,-1);
		printf("lua load error:%s\n",error);
	}
}

  • 流程解释

从做到右,栈顶→栈底
①arr

② 1 arr

③ arr
arr = {“A001”,“A002”,“A003”,“A004”,1}
打印栈顶A001
④ 2 arr
⑤ arr
arr = {“A002”,“A003”,“A004”,1,2} //压入表尾
打印栈顶A002
⑥A002从栈顶弹栈
lua和C++调用学习笔记系列一_第6张图片

四、lua给C++函数传递表参数

1)函数说明

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

  • 函数代码

2)代码

int CTestTable(lua_State* L)
{
    lua_pushnill(L);//在栈顶插入一个空值,防止把原先的表弹出去
    while(lua_next(L,1)!=0) //返回0表示结束
    {
		printf("key = %s ",lua_tostrin(L,-2));//先插入的key。后插入的value
		printf("value = %s",lua_tostrin(L,-1)); //打印value
		lua_pop(L,1);//顺便把value从栈底出站,函数从栈顶开始移除
	}
	return 0;
}
int main(int argc,char* argv[])
{
	lua_State* lua = lua_open();
	luaopen_base(lua);
	luaopen_string(lua);
	luaopen_table(lua);

	lua_register(lua,"CTestTable",CTestTable);


}
  • main.lua
local tab = {name = "xiaoming",age = "22",id = “007” }
CTestTable(tab);

lua和C++调用学习笔记系列一_第7张图片

  • lua函数补充
    1)lua_pop(L,num)函数从栈顶开始移除。
    ①当num>0时从栈顶移除指定个数 。
    ②当num=0时栈不受影响
    ③当num=-1时栈中元素全部移除
    2)lua_settop函数说明
    ①该函数用于指定栈的高度,栈只能从栈顶压栈,不能从栈底添加数据。所以栈底的数据会保持不变。
    当新的高度大于原来的高度时,会从栈顶压入数据,压入的数据不可用(因为是随机的)。
    ②当新的高度小于原来的高度时,会从栈顶移除多余的元素。
    ③当输入参数为负数时,表示从栈顶开始的索引(最栈顶元素为-1)。该函数会移除栈顶到该元素之间的所以元素。-1则无,-2 则移除-1 。-3则移除-1,-2。以此类推。但是负数编号不能超出栈底的负数索引,超出会抛出异常。lua_pop函数及是使用了该特性。
    3)接上 lua_pop函数说明
    #define lua_pop(L,n) lua_settop(L, -(n)-1)

①当n为-1时 lua_settop(L,0) 移除所有元素 ,正常
当n<-1 时,-(n)-1为正数,堆栈可能会高于原来的堆栈,此时却压入了新的栈,lua不会报错。违背了lua_pop的初衷。
②当n>0时,-(n)-1 等于负数,从栈顶开始移除n个参数,但是 -n-1不得超过栈底,会报错,及n不能超过当前栈中个数。
③如果不想从栈顶为起点移除除元素,而是移除从栈底起指定元素到栈顶的所有元素,直接用lua_settop即可。

3)lua获取表中特定key对应的value内容

  • 代码
lua_getfield(L,3,"name");//把name对应的值value压入栈顶
printf("%s \n",lua_tostring(L,-1));
  • main.cpp
int CTestTabble(lua_State* L)
{
	lua_getfield(L,1,"name");//name是第一个参数
	//,是栈底的位置
	printf("%s \n",lua_tostring(L,-1));//会把value压入到栈顶
}

你可能感兴趣的:(lua,lua,c++,学习)