自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在Java中使用Lua腳本語言

移動開發(fā) iOS
如何在Java中使用Lua腳本語言是本文要介紹的內容,主要是來學習LUA腳本語言在JAVA中如何來使用,Lua就不說了, 現(xiàn)在比較熱門,

如何在Java中使用Lua腳本語言是本文要介紹的內容,主要是來學習LUA腳本語言JAVA中如何來使用,Lua就不說了, 現(xiàn)在比較熱門, 語法也很簡單. 為了在Java中調用, 折騰了比較長的時間, 就把一些東西記在下面.來看詳細內容講解。

Lua是支持內嵌在C程序中的, 但是官方不支持Java. 在網(wǎng)上查了下, 有LuaJava開源庫, 拿來試用了一下, 發(fā)現(xiàn)這個庫還算比較完善的. 地址是

  1. http://www.keplerproject.org/luajava/ 

這個LuaJava實際上就是按照Lua官方文檔, 把Lua的C接口通過JNI包裝成Java的庫. 下載, 里面是一個.dll, 一個.jar. 把.dll放到java.library.path下, 再把.lib放到classpath中, helloworld運行OK.

但是, 測試的時候, 很快發(fā)現(xiàn)了第一個問題: 在調用LuaJava中提供的LuaState.pushInteger 方法的時候, 出現(xiàn)了錯誤 : Unsatisfied Link Error. 其他的LuaState.pushNumber方法倒是沒有問題. 用Depends工具看了下, 這個.dll居然沒有導出pushInteger這個函數(shù). 暈....

下載LuaJava的源代碼, 查看了下Luajava.c 和 Luajava.h, 發(fā)現(xiàn)果然里面有點問題, 在.h里面定義了JNI中對應Java函數(shù)的C函數(shù)

JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger

但是.c中沒有實現(xiàn)這個函數(shù). 無語, 看來大馬虎哪都有啊. 幸虧有源代碼, 照貓畫虎在Luajava.c中加上這個函數(shù)的實現(xiàn),

  1. JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger  
  2.    (JNIEnv * env, jobject jobj, jobject cptr, jint i)  
  3. {  
  4.     lua_State * L = getStateFromCPtr( env , cptr );  
  5.     lua_pushinteger(L, i);  

然后編譯. 編譯也出現(xiàn)了問題了, 官方文檔中說可以用VC++來Build, 但是沒有說官方用的是什么版本. 我用VC2005就不行. 好在Luajava比較小, 就一個.h 一個 .c , 在VC中新建一個.dll項目, 把文件加進去, 修改一下build參數(shù) (Include 需要加上lua的頭文件, lib中需要加上lua的.lib文件, 另外要選上 Compile as C Code (/TC) ) Build, 通過了.

這時再在Java中調用pushInteger方法就沒有問題了.

在測試中, 發(fā)現(xiàn)Luajava提供的文檔中, 對于Lua腳本怎么調用Java對象/方法很詳細, 但是在Java中怎么調用Lua函數(shù)/取得返回值 就沒有. 參考了http://www.lua.org/manual/5.1/manual.html#lua_CFunction 的Lua C文檔, 實現(xiàn)了傳遞對象到Lua中并取得返回值的代碼:

Test1: 測試傳遞簡單類型, 并取得返回值:

Lua 腳本(test.lua):

  1. function test(a,b)  
  2.     return a+b  
  3. end 

Java代碼:

  1. static {  
  2.         //加載Lua5.1.dll, 因為LuaJava最后還是要調用Lua的東西  
  3.         System.loadLibrary("lua5.1");  
  4.     }  
  5.       
  6.     public static void main(String[] argu) throws LuaException {  
  7.           
  8.         LuaState L = LuaStateFactory.newLuaState();  
  9.  
  10.         L.openLibs();  
  11.  
  12.         //讀入Lua腳本  
  13.         int error = L.LdoFile("test.lua");  
  14.         if (error != 0) {  
  15.             System.out.println("Read/Parse lua file error. Exit.");  
  16.             return;  
  17.         }   
  18.           
  19.         //找到函數(shù)test  
  20.         L.getField(LuaState.LUA_GLOBALSINDEX, "test");  
  21.         //參數(shù)1壓棧  
  22.         L.pushInteger(1);  
  23.         //參數(shù)2壓棧  
  24.         L.pushInteger(2);  
  25.         //調用!! 一共兩個參數(shù), 1個返回值  
  26.         L.call(2, 1);  
  27.         //保存返回值, 到a中  
  28.         L.setField(LuaState.LUA_GLOBALSINDEX, "a");  
  29.         //讀入a  
  30.         LuaObject l = L.getLuaObject("a");  
  31.         //打印結果.  
  32.         System.out.println("Result is " + l.getString());  
  33.         L.close();  

測試2: 傳遞Java對象

  1. class Value {  
  2.     public int i;  
  3.     public void inc() {  
  4.         i++;  
  5.     }  
  6.     public int get() {  
  7.         return i;  
  8.     }  
  9.     public String toString() {  
  10.         return "Value is " + i;  
  11.     }  

Lua腳本: (該腳本中調用兩次對象的inc方法, 并調用get方法輸出結果)

  1. function test1(v)  
  2.     v:inc();  
  3.     v:inc();  
  4.     print("In lua: " .. v:get());  
  5.     return v  
  6. end 

Java 代碼: (前面都一樣, 略)

  1. //找到函數(shù)test1  
  2. L.getField(LuaState.LUA_GLOBALSINDEX, "test1");  
  3. //生成新的對象供測試  
  4. Value v = new Value();  
  5. //對象壓棧  
  6. L.pushObjectValue(v);  
  7. //調用函數(shù)test1, 此時1個參數(shù), 1個返回值  
  8. L.call(1, 1);  
  9. //結果放在b中.  
  10. L.setField(LuaState.LUA_GLOBALSINDEX, "b");  
  11. LuaObject l = L.getLuaObject("b");  
  12. System.out.println("Result is " + l.getObject()); 

運行結果:

  1. Result is Value is 2  
  2. In lua: 2 

和預期的一致.

實現(xiàn)一個怪物的創(chuàng)建,把lua里的設定當作初始狀態(tài)傳給monstor,名字為sample monstor,防御10,攻擊10,生命100

1.先導入lib--luajava-1.1.jar

  1. import org.keplerproject.luajava.LuaState;  
  2. import org.keplerproject.luajava.LuaStateFactory;  
  3.  
  4. public class Load{  
  5. LuaState luaState;  
  6. /**  
  7. * Constructor  
  8. * @param fileName File name with Lua .  
  9. */  
  10. Load(final String fileName) {  
  11. this.luaState = LuaStateFactory.newLuaState();  
  12.  
  13. this.luaState.openLibs();  
  14.    this.luaState.LdoFile(fileName);  
  15.  
  16. }  
  17. /**  
  18. * Ends the use of Lua environment.  
  19. */  
  20. void close() {  
  21. this.luaState.close();  
  22. }  
  23. /**  
  24. * Call a Lua inside the Lua to insert  
  25. * data into a Java object passed as parameter  
  26. * @param Name Name of Lua .  
  27. * @param obj A Java object.  
  28. */  
  29. void run(String Name, Object obj) {  
  30. this.luaState.getGlobal(Name);  
  31. this.luaState.pushJavaObject(obj);  
  32. this.luaState.call(1,0);  
  33. }  
  34. }  
  35.  
  36. public class Monster{  
  37. /* Info */  
  38. protected String race;  
  39. protected int defense;  
  40. protected int attack;  
  41. protected int life;  
  42. /* */  
  43. private Load ;  
  44. public Monster(String race) {  
  45. /* Loads Lua for this race.*/  
  46. this. = new Load(race+".lua");  
  47. /*Call Lua create .*/  
  48. .run("create", this);  
  49. }  
  50.  
  51. public void setRace(String race) {  
  52.    this.race = race;  
  53. }  
  54. public String getRace() {  
  55. return race;  
  56. }  
  57. public int getDefense() {  
  58. return this.defense;  
  59. }  
  60. public void setDefense(int defense) {  
  61. this.defense = defense;  
  62. }  
  63. public int getLife() {  
  64. return this.life;  
  65. }  
  66. public void setLife(int life) {  
  67. this.life = life;  
  68. }  
  69. public void setAttack(int attack) {  
  70. this.attack = attack;  
  71. }  
  72. public int getAttack() {  
  73. return this.attack;  
  74. }  
  75. }  
  76.  
  77. monstor.lua---  
  78.  
  79. create(monster)  
  80. monster:setRace("Sample Monster")  
  81. monster:setDefense(10)  
  82. monster:setAttack(10)  
  83. monster:setLife(100)  
  84. end 

但總是拋出這個錯誤:

  1. PANIC: unprotected error in call to Lua API (Invalid method call. No such method.) 

不知為何,以后用到的時候再research.

已經(jīng)查出來,原來在Monster類中少了個方法:

  1. public void setRace(String race) {  
  2.    this.race = race;  

怪不得會找不到,

要在一lua文件a.lua里導入其他的lua文件b.lua,用require "b"

如果要從lua中運算后得到返回參數(shù),則需要做一下修改:在lua文件中改成:

  1. create(monster)  
  2. monster:setRace("Sample Monster")  
  3. monster:setDefense(10)  
  4. monster:setAttack(10)  
  5. monster:setLife(100)  
  6. return monster  
  7. end 

在Load.java中的run改成如下:

  1. void run(String Name, Object obj) {  
  2.    this.luaState.getGlobal(Name);  
  3.    this.luaState.pushJavaObject(obj);  
  4.    this.luaState.call(1, 1);// 一個參數(shù),0個返回   
  5.    try {  
  6.     Object object =luaState.getObjectFromUserdata(1);  
  7.    } catch (LuaException e) {  
  8.     e.printStackTrace();  
  9.    }  

小結:如何在Java中使用Lua腳本語言的內容介紹完了,希望通過本文的學習能對你有所幫助!

責任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關推薦

2011-08-23 09:56:52

UnicodeLua

2011-08-23 09:44:28

LUA腳本

2011-08-25 13:22:40

CEGUILua腳本

2011-09-07 09:51:27

Javascript

2010-07-01 09:29:15

Java腳本語言javax.scrip

2011-08-22 18:00:53

Lua語言

2011-08-22 16:59:28

Lua

2011-08-25 11:02:04

2011-08-25 10:40:21

Lua游戲

2011-08-22 17:41:23

LUA 腳本 語言

2011-08-22 18:08:09

Lua腳本

2011-08-24 13:32:17

2011-06-22 14:07:42

Lua

2022-11-23 08:14:42

bash 腳本test 命令

2011-08-25 14:26:40

LUA數(shù)據(jù)文件

2010-02-26 13:03:31

Python腳本語言

2022-12-22 20:47:01

腳本循環(huán)結構

2021-03-14 09:28:24

Linux Shell腳本

2022-10-09 10:18:44

LinuxShell腳本

2021-09-10 10:30:22

Java代碼
點贊
收藏

51CTO技術棧公眾號