在C++使用LUA交互,LUA實現閉包,C++/LUA相互閉包
來源:程序員人生 發布時間:2014-12-07 09:58:34 閱讀次數:2662次
LUA可謂是配置文件神器,具體功能用過才知道,接近兩年沒用了抽了倆小時熟習了下基本的用法。
包括C/LUA堆棧操作 函數相互調用 和LUA的閉包 C++和LUA相互閉包
想要靈活使用LUA必須先要學習 LUA和C的堆棧交互模型 類似于匯編函數調用方式了 很成心思。
要學習LUA首先要理解LUA和C/C++交互的堆棧lua_State 這里援用網友的1篇文章很詳細
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程序通過1個堆棧交換數據: 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
",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);
FOR_LIST(1,10,1,lua); //
//lua_pop(lua,3) ;//依照堆棧 落后先出的方式彈出3個參數
n=lua_gettop(lua);
printf("lua堆棧中有%d個參數
",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 腳本調用成功!
");
}
//彈出堆棧所有數據
CLEAR(lua);
///加載lua腳本 并且編譯運行lua腳本
//從當前工作目錄加載
if(luaL_dofile(lua,"./c.lua"))
{
printf("lua腳本加載成功!
");
}
lua_getglobal(lua,"num1");//加載到堆棧
lua_getglobal(lua,"num2");//加載到堆棧
lua_getglobal(lua,"str1"); //加載字符串
int num1 = lua_tointeger(lua, ⑶); //逆向取值 從堆棧 LUA堆棧為雙向
printf("num1:%d
",num1);
n=lua_gettop(lua);
int num2 = lua_tointeger(lua, ⑵); //逆向取值 從堆棧 LUA堆棧為雙向
printf("num2:%d
",num2);
n=lua_gettop(lua);
printf("lua堆棧中有%d個參數
",n);
CLEAR(lua);
//加載函數到堆棧
//調用的是無參函數
lua_getglobal(lua,"testHello") ;
n=lua_gettop(lua);
printf("lua堆棧中有%d個參數
",n);
//lua 函數調用會自動清算堆棧
lua_pcall(lua, 0,0,0);
n=lua_gettop(lua);
printf("lua堆棧中有%d個參數
",n);
lua_getglobal(lua,"Closer") ; //函數壓入棧頂
lua_pushinteger(lua,1);
lua_pushinteger(lua,2);//壓入參數
//閉包函數調用
if(LUA_OK!=lua_pcall(lua,2,1,0))
{
printf("函數調用失敗!
");
return 0 ;
}
int result=lua_tointeger(lua,⑴);//取出棧頂數據
printf("Closer result:%d
",result);
//注意清算堆棧返回值在 棧頂 POP1下
lua_pop(lua,1);
n=lua_gettop(lua);
printf("lua堆棧中有%d個參數
",n);
/////LUA調用C++函數
//注冊函數
lua_register(lua, "CallC", callCPP);
//從當前工作目錄加載
if(luaL_dofile(lua,"./c1.lua"))
{
printf("lua c1腳本加載成功!
");
}
///C/LUA閉包調用
lua_pushcfunction(lua,callCPP);
lua_setglobal(lua,"CallCT");//設置lua中的調用
lua_getglobal(lua,"CloserT");//加載lua閉包函數到C++堆棧
lua_pushinteger(lua,2); //函數堆棧參數1定要正確
lua_pushinteger(lua,3);
lua_pcall(lua,2,0,0);
n=lua_gettop(lua);
printf("lua堆棧中有%d個參數
",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
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈