標籤:col 目的 error new 建立 完成 解釋 資訊 主程
1、首先說下目的,為什麼要這麼做 ?
正式項目中,希望主程式盡量不做修改,於是使用C/C++完成功能的主幹(即不需要經常變動的部分)用lua這類輕量級的解釋性語言實現一些存在不確定性功能邏輯;所以,程式功能如有問題,只需對lua指令碼作出修改,而修改指令碼的好處是簡單高效,改完指令碼後重新執行程式便能看到效果。
2、具體怎麼做?
一般來說,C/C++調用lua介面或是資料互動,首先要做的是包含lua相關操作的標頭檔以及lua庫相關的標頭檔,然後調用介面建立lua環境、用操作棧的規則和lua互動資料或參數(調用lua函數);執行所需操作或是取得所需資料後銷毀lua環境。以下用源碼進行詳細解釋:
①、C++源檔案
1 //1、包含標頭檔 2 extern "C" 3 { 4 #include<lua5.2/lua.h> 5 #include<lua5.2/lauxlib.h> 6 #include<lua5.2/lualib.h> 7 } 8 //2、建立lua環境 9 lua_State *L = luaL_newstate();10 if(L == NULL)11 {12 cout<<"Creat Lua State Error !"<<endl;13 return 1;14 }15 //如需在終端輸出列印資訊,庫是必須載入的,否則看不到lua的print資訊16 luaL_openlibs(L);17 //3、載入lua指令碼18 const string lua_path = "../scripts/";19 const string file = "Function.lua";20 string script = lua_path + file ;21 int ret = luaL_dofile(L ,script.c_str());22 if(ret)23 {24 cout<<"Lua doFile Error !"<<endl;25 return 1;26 }27 //4、呼叫指令碼中已寫好的函數28 //a、無參函數29 lua_getglobal(L, "ruler"); //函數名為ruler30 lua_pcall(L,0,0,0); //用保護模式調用lua函數,入參個數為0、出參個數為0、無自訂錯誤處理31 32 //b、有參函數33 lua_getglobal(L, "add"); //函數名為add34 lua_pushnumber(L, number1); //第一個入參35 lua_pushnumber(L, number2); //第二個入參 36 lua_pcall(L,2,1,0); //函數有兩個入參,一個出參,所以函數形式為add(a,b)37 //5、獲得傳回值,單回值情況下調用完成後lua會把結果放到棧頂,多傳回值時,按照規則存放,具體查API38 if(lua_isnumber(L,-1))39 {40 cout<<"the result is :"<<lua_tonumber(L,-1)<<endl;41 }42 //6、銷毀lua環境43 lua_close(L);
②、lua指令碼
1 //7、add,lua指令碼內容2 function add(a,b)3 return a+b;4 end5 6 function ruler()7 print("this is some thing need to tell you !!!");8 end
3、結語:
總之,lua和C/C++互動必須依靠媒介——棧;用lua作為設定檔時,內容為靜態,組織為table,C++通過table相關介面操作資料;當用lua作為較為複雜的函數語言時,當前lua中所有全域函數都可以被宿主語言調用,且如果要用lua輸出列印資訊以便調試,此時必須open lua庫,否則將看不到print相關內容,且全域的print都會導致difile()失敗。
典型操作就這兩類,其餘的,都可以通過查閱API手冊嘗試去使用,have fun !
簡述C/C++調用lua中實現的自訂函數