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

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

时间: 2024-10-25 06:48:23

在C++使用LUA交互,LUA实现闭包,C++/LUA相互闭包的相关文章

Win32下 Qt与Lua交互使用(三):在Lua脚本中connect Qt 对象

话接上文.笔者为了方便使用Lua,自己编写了一个Lua的类.主要代码如下: QLua.h 1 #ifndef QLUA_H 2 #define QLUA_H 3 4 // own 5 #include "include/lua.hpp" 6 7 // qt 8 #include <QObject> 9 #include <QFile> 10 #include <QDebug> 11 12 #include <QWidget> 13 #in

Win32下 Qt与Lua交互使用:配置Qt下Lua运行环境

Lua与C++之间可以实现非常强的交互性.Lua中可以使用C++中的函数,C++中也可以使用Lua中的函数.由此可以引发出很多奇思妙想了. 简单来说,Lua动态的特性补充了C++的功能.当然,也看你具体怎么用. 笔者经常使用Qt,故准备将Qt和Lua结合在一起.想象一下在Lua脚本中调用如下代码: w = QWidget:new() w:show() 然后弹出一QWidget的窗口,是多么感人的一件事情呀. 好,下面开始配置环境吧. 1. 下载Lua 5.1.目前的最新版本是5.2,但是因为使用

win平台下搭建cocos2dx 3.1.1 lua开发环境 VS2012+sublime text+lua 5.2.3

安装vs2012 安装python 2.7.3和环境配置 下载cocos2dx 3.1.1 用vs2012打开test项目 右键运行生成解决方案  cocos2dx3.1.1 新建lua项目 cocos2dx 3.1.1引擎目录依次找到tools cocos2d-console bin,  把cocos.py拖到在dos的command(cmd)中 然后继续输入新建项目的信息: new game -p com.test.app  -l lua 我们这就可以在屏幕中提示的路径找到新建的项目game

Lua学习之加载其他lua文件

Lua 中提供了模块的概念,模块类似一个封装库或者 C++ 中的一个类,可以将公用的部分提到一个文件中,以 API 的形式供其他 lua 文件调用. Lua 中的模块其实就是包含变量.函数等已知元素组成的 table, 本质上是一个 table. 一.模块的声明 创建一个名称为 LearnModule.lua 的文件,并在此文件中实现下列代码: -- 定义一个名为ModuleT的模块,模块的本质就是一个table,内部包含变量和函数等 ModuleT = {} -- 定义一个变量 ModuleT

Lua 学习之基础篇七&lt;Lua Module,Package介绍&gt;

Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require (modname) 加载一个模块. 这个函数首先查找 [package.loaded] 表, 检测 modname 是否被加载过. 如果被加载过,require 返回 package.loaded[modname] 中保存的值. 否则,它会为模块寻找加载器. require 遵循 [package.

深入理解javascript原型和闭包(15)——闭包

http://www.cnblogs.com/wangfupeng1988/p/3994065.html 深入理解javascript原型和闭包(15)——闭包

从闭包案例中学习闭包的作用,会不会由你。

在文章初识js中的闭包中讲解了闭包的一些概念,但是对于初学者来说可能并不是特别的容易理解,我今天用两个案例来解释闭包可能会好理解一些,在讲案例之前,我们需要了解一些闭包的概念.在看这篇文章之前,请先看上面的那篇文章,不然效果不会太好. 闭包的理解: 所谓的闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰. 闭包的创建: 一个函数中嵌套另外一个函数,并且将这个函数return出去,然后将这个return出来的函数保存到了一个变量中,那么就创建了一个闭包. 为啥要学闭包之没有使

print(函数.__closure__) 来判断是不是闭包, 返回cell , 是闭包, 返回None 则不是闭包

print(函数.__closure__) 来判断是不是闭包,  返回cell , 是闭包,       None 则不是闭包 原文地址:https://www.cnblogs.com/jack20181017/p/9893159.html

python闭包,以及修改闭包里面的数据

什么是闭包,简单理解闭包就是一个特殊的空间,闭包相当与于一个嵌套函数,里面函数用到了外面函数的变量,外面函数用到了里面函数的返回值.可以当做实参进行传递,可以实现python装饰器的功能. 看上面如图代码,定义了line的函数,需要传2个参数,又在里面定义了一个create_z的函数,需要传1个参数,在打印结果是时候,里面函数需要用到line函数的x,y参数,在调用时候line的参数传递到了create_z里面,create_z函数本身需要传递z参数,而调用line函数会返回create_z,即