在C++使用LUA交互,LUA实现闭包,C++/LUA相互闭包

简介: LUA可谓是配置文件神器,具体功能用过才知道,接近两年没用了抽了俩小时熟悉了下基本的用法。 包括C/LUA堆栈操作 函数相互调用 以及LUA的闭包 C++和LUA相互闭包 想要灵活使用LUA必须先要学习 LUA和C的堆栈交互模型 类似于汇编函数调用方式了 很有意思。

LUA可谓是配置文件神器,具体功能用过才知道,接近两年没用了抽了俩小时熟悉了下基本的用法。

包括C/LUA堆栈操作 函数相互调用 以及LUA的闭包 C++和LUA相互闭包

想要灵活使用LUA必须先要学习 LUA和C的堆栈交互模型 类似于汇编函数调用方式了 很有意思。

要学习LUA首先要理解LUA和C/C++交互的堆栈lua_State  这里引用网友的一篇文章很详细

http://wind-catalpa.blog.163.com/blog/static/1147535432013119103150929/

上代码

C++代码

<span style="font-size:14px;color:#000000;">#include "string.h"
extern "C"
{

#include "lualib.h"  //包含lua lib
#include "lauxlib.h"  //辅助函数 
};
#pragma  comment(lib,"lua.lib")
//Lua和C程序通过一个堆栈交换数据: lua_State
lua_State* GetLua()
{
	lua_State* lu = luaL_newstate(); 	/*创建Lua对象*/  
	luaL_openlibs(lu); // 打开所有 共享库函数 到lua 对象 
	return lu ;
}

//批量数据压入堆栈
#define FOR_PUSH(I,J,STEP,LUA)  \
	for(int i=I;i<=J;i+=STEP)   \
{                       \
	lua_pushinteger(LUA,i);\
}
//取出堆栈中指定index的数据 
//打印堆栈数据
#define FOR_LIST(I,J,STEP,LUA)  \
	for(int i=I;i<=J;i+=STEP)   \
{                       \
	int n=lua_tointeger(LUA,i);  \
	printf("堆栈中Index:%d,数据:%d\n",i,n);   \
}

#define CLEAR(LUA)   \
	 for(int i=1;i<=lua_gettop(LUA);i++) \
	    lua_pop(LUA,i)

//返回1个结果  
//函数原型具体参照LUA5.2文档
int callCPP(lua_State *lua)    
{    
	int a = lua_tointeger(lua, 1);    
	int b = lua_tointeger(lua, 2);    
	lua_pushnumber(lua, a+b);    //结果压栈    
	return 1;             
}    


int _tmain(int argc, _TCHAR* argv[])
{  
	//获取C和Lua交互的堆栈指针
	lua_State *lua =GetLua();
	if(lua==nullptr)
	{ 
		printf("Lua Open Error");
		return  0;
	}
	//关于Lua的堆栈操作
	FOR_PUSH(1,10,1,lua);//循环顺序入堆栈的参数
	int n=lua_gettop(lua);
	printf("lua堆栈中有%d个参数\n",n);
	FOR_LIST(1,10,1,lua); //
	//lua_pop(lua,3) ;//按照堆栈 后进先出的方式弹出三个参数 
	n=lua_gettop(lua);
	printf("lua堆栈中有%d个参数\n",n);
	FOR_LIST(1,n,1,lua); //
	//执行简单内存LUA脚本
	char*pLua="print (\"hello,lua!\")";  
	luaL_loadbuffer(lua,pLua,strlen(pLua),"testLuaScript0Chunk");
	if(LUA_OK==lua_pcall(lua, 0,0,0))  
	{
		printf("lua 脚本调用成功!\n");
	}
	//弹出堆栈所有数据
	CLEAR(lua);


	///加载lua脚本  并且编译运行lua脚本
	//从当前工作目录加载
	if(luaL_dofile(lua,"./c.lua")) 
	{
		printf("lua脚本加载成功!\n");
	}
	 lua_getglobal(lua,"num1");//加载到堆栈
	 lua_getglobal(lua,"num2");//加载到堆栈
	 lua_getglobal(lua,"str1"); //加载字符串
	 int num1 = lua_tointeger(lua, -3);    //逆向取值 从堆栈  LUA堆栈为双向  
	 printf("num1:%d\n",num1);
	 n=lua_gettop(lua);
	 int num2 = lua_tointeger(lua, -2);    //逆向取值 从堆栈  LUA堆栈为双向  
	 printf("num2:%d\n",num2);
	 n=lua_gettop(lua);
	 printf("lua堆栈中有%d个参数\n",n);
	 CLEAR(lua);
	 //加载函数到堆栈 
	 //调用的是无参函数
	 lua_getglobal(lua,"testHello") ;
	 n=lua_gettop(lua);
	 printf("lua堆栈中有%d个参数\n",n);
	 //lua 函数调用会自动清理堆栈
	 lua_pcall(lua, 0,0,0);
	 n=lua_gettop(lua);
	 printf("lua堆栈中有%d个参数\n",n);

	 lua_getglobal(lua,"Closer") ; //函数压入栈顶
	 lua_pushinteger(lua,1);
	 lua_pushinteger(lua,2);//压入参数 
	 //闭包函数调用
	 if(LUA_OK!=lua_pcall(lua,2,1,0))
	 {
		 printf("函数调用失败!\n");
		 return 0 ;
	 }

	 int result=lua_tointeger(lua,-1);//取出栈顶数据
     printf("Closer result:%d\n",result);
	 //注意清理堆栈返回值在 栈顶 POP一下 
	 lua_pop(lua,1);
	 n=lua_gettop(lua);
	 printf("lua堆栈中有%d个参数\n",n);
	 /////LUA调用C++函数
	 //注册函数
	 lua_register(lua, "CallC", callCPP);
	 //从当前工作目录加载
	 if(luaL_dofile(lua,"./c1.lua")) 
	 {
		 printf("lua  c1脚本加载成功!\n");
	 }
	 ///C/LUA闭包调用
	lua_pushcfunction(lua,callCPP);
	lua_setglobal(lua,"CallCT");//设置lua中的调用
	lua_getglobal(lua,"CloserT");//加载lua闭包函数到C++堆栈
	lua_pushinteger(lua,2); //函数堆栈参数一定要正确
	lua_pushinteger(lua,3);
	lua_pcall(lua,2,0,0);
	n=lua_gettop(lua);
	printf("lua堆栈中有%d个参数\n",n);

	return 0;
}

</span>
c.lua 和c1.lua文件

--c.lua

str1="hello,I am Luaer"
num1=2
num2=3
--测试函数输出 str1
function testHello()
   print(str1)
end
--lua实现闭包
function  Closer(i,j)
   function add(i,j)
      return i+j
   end
   return add(i,j)
end

function CallC(a,b)
  return callCPP(a,b)
end



--c1.lua call C++ function
num=CallC(3,4)
print ("num is:",num)
--c++和lua相互闭包
function CloserT(a,b)
    num1=CallCT(a,b)
    print ("C++/LUA相互闭包 Num1 is:",num1)
end






目录
相关文章
|
前端开发 算法 数据可视化
第三代软件开发-C++&QML交互
欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。 在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。 在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资
|
4月前
|
缓存
Lua语法(二)——闭包/日期和时间
Lua语法(二)——闭包/日期和时间
92 0
|
7月前
|
JSON C语言 数据格式
C语言与lua通过json对象交互
C语言与lua通过json对象交互
136 1
|
7月前
|
编译器 C++
C/C++中的逻辑运算与汇编指令的交互
C/C++中的逻辑运算与汇编指令的交互
47 0
|
7月前
|
算法 编译器 C++
【C++ 关键字的混合使用 】C++深度探索:auto、static、constexpr的交互影响与应用
【C++ 关键字的混合使用 】C++深度探索:auto、static、constexpr的交互影响与应用
93 0
|
7月前
|
消息中间件 自然语言处理 Kubernetes
Lua闭包和Upvalue上值
Lua闭包和Upvalue上值
|
网络协议 Linux API
C/C++服务器和客户端交互笔记
Socket通信三要素:通信的目的地址、使用的端口号(http 80 / smtp 25)、使用的传输协议(TCP、UDP)。
174 0
|
Ubuntu 云计算 C++
C++与lua的结合,LuaBridge的使用及遇到的坑
C++与lua的结合,LuaBridge的使用及遇到的坑
|
C++
[✔️]lua中的function,在c++进行callback
[✔️]lua中的function,在c++进行callback
189 0
|
C++
[✔️]c++返回2个值给lua,tolua如何处理c++函数重载
[✔️]c++返回2个值给lua,tolua如何处理c++函数重载
139 0