下面將講解一下如何在iOS里調用Lua函數,以及Lua函數如何調用iOS本地函數。
轉載請注明出處。原文出處 http://www.cnblogs.com/winewind/archive/2012/09/06/2673094.html
1 lua_State *l; 2 l = lua_open();
lua_open 若要使用Lua,必須先初始化一個lua_State環境,以后的所有Lua相關操作都必須包含這個State。
1 void InitLua(lua_State* L) 2 { 3 /* Load Libraries */ 4 luaopen_base(L); 5 luaopen_table(L); 6 luaL_openlibs(L); 7 luaopen_string(L); 8 luaopen_math(L); 9 }
InitLua函數主要作用是用來打開初始化Lua庫
1 lua_close(L);
當不在使用Lua的時候記得調用lua_close來釋放lua_State。
1 int DKCALL(lua_State* L) 2 { 3 if (!lua_isnumber(L, 1)){ 4 return lua_error(L); 5 } 6 if (!lua_isnumber(L, 2)){ 7 return lua_error(L); 8 } 9 double a = lua_tonumber(L, 1); 10 double b = lua_tonumber(L, 2); 11 a>b?lua_pushnumber(L, a):lua_pushnumber(L, b); 12 return 1; 13 }
DKCALL是本次示例的一個核心函數,用來返回兩個參數中較大的那個值。
lua_tonumber是從棧中指定位置獲取數值。1代表第一個參數,以此類推。
lua_isnumber是用來檢查棧中指定是否是數值類型
lua_pushnumber 將數值壓入棧中
1 function lefthandcall(a, b) 2 local c = lhc(a, b); 3 print("LUA:", c); 4 return c; 5 end;
將這段腳本保存為s1.lua然后保存在iOS項目根目錄下,並在項目中添加該文件
可以看出lefthandcall是我們定義的Lua函數,功能就是調用lhc函數並返回lhc返回的值。
而里面的lhc函數卻沒有申明,lhc函數是一個iOS本地函數。如何在Lua腳本中調用iOS本地函數呢?下面將仔細講解到。
下面我們將開始在iOS項目里講解如何調用Lua腳本中的函數
首先,我們要指定我們腳本的位置,好方面后面的調用
1 NSString *scriptpath = [[[NSBundle mainBundle] resourcePath] 2 stringByAppendingPathComponent:@"s1.lua"];
scriptpath保存的就是腳本文件的絕對路徑
1 int iError = luaL_loadfile(L, scriptpath.UTF8String); 2 if (iError){ 3 printf("load script fail!\n"); 4 return iError; 5 } 6 iError = lua_pcall(L, 0, 0, 0); 7 if (iError){ 8 printf("execute script fail!\n"); 9 return iError; 10 }
lua_loadfile是加載lua腳本文件的函數。這里我們把scriptpath值傳入。
lua_pcall則是解釋這個腳本文件的函數。不解釋一邊腳本,lua環境里就沒有lhc的函數申明存在。
如果這兩步都通過了,那么我們就開始映射lua腳本中lhc函數和iOS本地函數的關系了。
先前我們不是建立了一個核心函數DKCALL。那么下面我們來映射lhc到這個本地函數上來
1 lua_pushstring(L, "lhc"); 2 lua_pushcfunction(L, DKCALL); 3 lua_settable(L, LUA_GLOBALSINDEX);
這里可以看到我們壓入了lhc函數名以及DKCALL函數地址,然后更新了全局表,用來在Lua環境中關聯lhc的虛函數和DKCALL實函數之間的關系。
那么,我們就可以測試一下lua腳本了,我們來在iOS環境里執行一下Lua腳本中的lefthandcall
1 lua_getglobal(L, "lefthandcall"); 2 lua_pushnumber(L, 15); 3 lua_pushnumber(L, 10);
lua_pushnumber的作用前面講解過,lefthandcall不是有兩個參數嗎,我們必須壓入兩次。
1 int Error = lua_pcall( L,2,1,0 );
lua_pcall 用來做一次lua的函數調用。
第二個參數 2 代表壓入的參數有兩個
第三個參數 1 代表該函數只返回一個結果(腳本類都能返回多個結果)
第四個參數 0 指定一個錯誤處理函數,這里我們沒有指定錯誤處理函數。
XCode Output
到這里我們看到從iOS環境里加載了一個s1.lua腳本並且調用了里面的lefthandcall函數
該函數執行過程中有一個lhc函數,lua在全局表中查找發現是一個本地函數調用,於是調用了DKCALL函數,計算並返回了一個結果
這個結果在s1.lua的腳本里打印到終端上來。
可以看出,Lua很容易就跟iOS環境結合在一起。並且我們可以使用Lua的特性來幫助我們簡化iOS的開發。