在C++使用LUA互動,LUA實現閉包,C++/LUA相互閉包,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_Statelua_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=2num2=3--測試函數輸出 str1function testHello() print(str1)end--lua實現閉包function Closer(i,j) function add(i,j) return i+j end return add(i,j)endfunction CallC(a,b) return callCPP(a,b)end
--c1.lua call C++ functionnum=CallC(3,4)print ("num is:",num)--c++和lua相互閉包function CloserT(a,b) num1=CallCT(a,b) print ("C++/LUA相互閉包 Num1 is:",num1)end