詳解在JAVA(J2ME)中使用Lua指令碼引擎kahlua

來源:互聯網
上載者:User

JAVA(J2ME)中使用Lua指令碼引擎kahlua是本文要介紹的內容,主要是來學習JAVS中如何來使用LUALua有幸被暴雪選中,在魔獸中大量應用,從而獲得了極快的發展,Lua也因此成為遊戲、軟體開發中指令碼語言的首選。Lua是一種十分簡潔的指令碼語言,不過寫起來並不是很簡單,當然過分的簡化使得程式本身有些混亂。具體的語言教程在網上有很多,這裡就不再說了。

kahlua最初是為J2ME設計的,現在已經擴充到J2SE,項目地址是http://code.google.com/p/kahlua/,在這裡可以下載到原始碼及編譯好的jar包。在實際應用中我發現J2ME中匯入jar包很困難,弄了好幾天也沒有成功,只好將原始碼放在在工程的目錄裡一同編譯。kahlua可以識別*.lua及*.lbc檔案,*.lbc是編譯後的lua檔案,項目中一般使用這種檔案,因為不會泄露lua檔案的內容。可以到http://www.lua.org上下載一個lua的運行環境,安裝後會自動添加安裝路徑到系統變數,此時在cmd中運行luac程式就可以編譯指令碼,命令是luac -o f.lbc d:\f.lua,詳情看協助文檔。

我下的kahlua是kahlua-release-20090611.zip原始碼包,解壓後是一個Ant工程,將src目錄下的內容及resource中的stdlib.lua(lbc)檔案複製到J2ME項目中src下。在編程之前首先說明一點,在程式中指定檔案的路徑時要注意對應工程檔案的位置。我的工程的src檔案夾對應程式中的根目錄,比如說上的/src/stdlib.lua在程式中就是/stdlib.lua。

lua指令碼語言中一個獨特的資料類型就是表,表其實就是java中的map、雜湊表,比如說下面一個表:

 
  1. T1 = {} -- 定義一個空表  
  2. T1[1]=10 --定義表的內容  
  3. T1["John"]={Age=27, Gender="Male"} 

而每一個指令檔實際上就是一個大表,每一個變數、方法都是表的成員,因此指令碼的變數預設都是全域的,而且也可以定以方法為變數,kahlua正是依據這個概念來的。

1、初始化:

 
  1. LuaState state=new LuaState(System.out);  
  2. UserdataArray.register(state);  
  3. OsLib.register(state);  
  4. LuaCompiler.register(state); 

se.krka.kahlua.vm.LuaState對象是kahlua引擎的核心,一切操作都由它來完成,在產生LuaState對象後再進行一些註冊。

2、擷取全域表:

 
  1. LuaTable table=state.getEnvironment();  
  2.  
  3. LuaTable有一系列函數添加、擷取指令碼內容,最常用的有:  
  4. void rawset(Object key, Object value);//新增內容  
  5. Object rawget(Object key);//擷取內容 

3、載入指令碼:

 
  1. InputStream is=this.getClass().getResourceAsStream(scriptName);  
  2. //scriptName為指令檔的路徑  
  3. LuaClosure closure=LuaCompiler.loadis(is , "lua" , table);  
  4. //LoadCompiler為編譯器,loadis為載入輸入資料流的方法  
  5. //is為輸入資料流;"lua"為編譯器的名字,好像任一字元串都可以;table為全域表  
  6. //LuaClosure為指令碼編譯後的語句。 

整個指令碼編譯後相當於一個大的方法,並將其添加到全域表。

4、執行指令碼:

 
  1. sate.call(closure, null);  
  2. LuaState的public Object call(Object fun, Object[] args) 

方法是用來執行全域表中的方法,前面說到,整個指令碼編譯後是作為一個方法存入全域表的,因此也可以用這個方法執行指令碼。

5、方法:

public Object call(Object fun, Object[] args)中fun為函數對象,args為參數

1)在Java中調用Lua方法

 
  1. state.call( table.rawget("say") , new String[]{"Hello!"}); 

即從全域表中取出函數並執行。

2)在Lua中調用Java方法

首先產生一個繼承自JavaFunction介面的類,然後添加到全域表中

JavaFunction只有一個public abstract int call(LuaCallFrame callFrame, int nArguments)方法,其中callFrame用於擷取輸入參數及指定傳回值,nArguments擷取輸入參數數量。傳回值為返回參數的個數,因為lua函數可以有多個傳回值的。

 
  1. class JavaFunctionSay implements JavaFunction{  
  2. public int call(LuaCallFrame frame, int arg) {  
  3. String str=BaseLib.rawTostring(frame.get(0));//擷取輸入參數  
  4. say(str);//執行對應Java內容  
  5. frame.push("result");//返回參數  
  6. return 1;  
  7. }   

再用table.rawset("say", new JavaFunctionSay());添加到全域表,這樣就可以在對應Lua指令碼中使用say方法了。

附註:

kahlua顯示中文有問題,應該是編碼不正確,修改LexState中String newstring( byte[] chars, int offset, int len )方法的第一行編碼為"GBK"後好像就可以了。
本人在windows中使用用luac產生的lbc時出錯..檔案不支援中文,有中文就會報錯,而英文就能順利通過,想來可能和字元編碼有關係...想在lbc中使用中文,本人的方法是:

 
  1. File luascript = new File("E:\\getWeather.lua");//--其實什麼尾碼名無所謂的  
  2. File lbcscript=new File("C:\\Users\\信豐boy\\getWeather.lbc");  
  3. closure = LuaCompiler.loadis(new FileInputStream(luascript), "信豐boy",table);//"信豐boy"這個字串是可以隨意的.其作用是表示範圍.  
  4. OutputStream os=new FileOutputStream(lbcscript);  
  5. closure.prototype.dump(os);//這樣就把lbc格式的位元組碼檔案寫到"C:\\Users\\信豐boy\\getWeather.lbc"了.  
  6. os.close(); 

當下次要調用的時候

 
  1. File lbcscript=new File("C:\\Users\\信豐boy\\getWeather.lbc");  
  2. closure = LuaPrototype.loadByteCode(new FileInputStream(lbcscript), table); 

ps:kuhlua不支援gfind函數,所有你得用find函數ps:kuhlua不支援gfind函數,所有你得用find函數。

小結:詳解在JAVA(J2ME)中使用Lua指令碼引擎kahlua的內容介紹完了,希望通過本文的學習能對你有所協助!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.