luajava調用
要在Java上使用Lua腳本,必須有關於Lua腳本解釋器以及Java程序可以訪問這些腳本的相關API,即相關類庫。可以使用一個叫做LuaJava的開源項目,可以在www.keplerproject.org/luajava/ 找到LuaJava的類庫以及源代碼,使用文檔資等
❷ java調用lua怎麼傳參數
這個最好用jni+ lua/c api才可以。或者用別人在jvm裡面實現的lua虛擬機
❸ 用Java編寫一個程序,要求如下:
1.內部使用 C 的 longjmp 機制讓出一個協程。因此,如果一個 C 函數 foo 調用了一個 API 函數, 而這個 API 函數讓出了(直接或間接調用了讓出函數)。 由於 longjmp 會移除 C 棧的棧幀, Lua 就無法返回到 foo 里了。
2.為了迴避這類問題, 碰到 API 調用中調用讓出時,除了那些拋出錯誤的 API 外,還提供了三個函數: lua_yieldk, lua_callk,和 lua_pcallk 。 它們在讓出發生時,可以從傳入的 延續函數 (名為 k 的參數)繼續運行。
3.我們需要預設一些術語來解釋延續點。對於從 Lua 中調用的 C 函數,我們稱之為 原函數。從這個原函數中調用的上面所述的三個 C API 函數我們稱之為 被調函數。 被調函數可以使當前線程讓出。 (讓出發生在被調函數是 lua_yieldk, 或傳入 lua_callk 或 lua_pcallk 的函數調用了讓出時。)
4.假設正在運行的線程在執行被調函數時讓出。當再次延續這條線程,它希望繼續被調函數的運行。 然而,被調函數不可能返回到原函數中。 這是因為之前的讓出操作破壞了 C 棧的棧幀。 作為替代品,Lua 調用那個作為被調函數參數給出的 延續函數 。 正如其名,延續函數將延續原函數的任務。
5.注意這里那個額外的顯式的對延續函數的調用:Lua 僅在需要時,這可能是由錯誤導致的也可能是發生了讓出而需要繼續運行,才會調用延續函數。 如果沒有發生過任何讓出,調用的函數正常返回, 那麼 lua_pcallk (以及 lua_callk)也會正常返回。 (當然,這個例子中你也可以不在之後調用延續函數, 而是在原函數的調用後直接寫上需要做的工作。)
6.Lua 會把延續函數看作原函數。延續函數將接收到和原函數相同的 Lua 棧,其接收到的 lua 狀態也和 被調函數若返回後應該有的狀態一致。 (例如, lua_callk 調用之後, 棧中之前壓入的函數和調用參數都被調用產生的返回值所替代。) 這時也有相同的上值。 等到它返回的時候,Lua 會將其看待成原函數的返回去操作。
7.我們需要預設一些術語來解釋延續點。對於從 Lua 中調用的 C 函數,我們稱之為 原函數。 從這個原函數中調用的上面所述的三個 C API 函數我們稱之為 被調函數。 被調函數可以使當前線程讓出。 (讓出發生在被調函數是 lua_yieldk, 或傳入 lua_callk 或 lua_pcallk 的函數調用了讓出時。)
8.假設正在運行的線程在執行被調函數時讓出。當再次延續這條線程,它希望繼續被調函數的運行。 然而,被調函數不可能返回到原函數中。 這是因為之前的讓出操作破壞了 C 棧的棧幀。 作為替代品,Lua 調用那個作為被調函數參數給出的 延續函數 。 正如其名,延續函數將延續原函數的任務。
希望能幫到你,謝謝!
❹ lua調用 android/ios有哪幾種方式,請分別描述一下
//Android:
//所需包:
importorg.keplerproject.luajava.LuaState;
importorg.keplerproject.luajava.LuaStateFactory;
//初始化:
LuaStatel=LuaStateFactory.newLuaState();
l.openLibs();
//載入代碼:
StringluaCode="functiontest(a,b) returna+b end";
if(l.LdoString(luaCode)==0){/*載入成功*/}else{/*載入失敗*/}
//設置主方法:
StringmainFunction="test";
l.getField(LuaState.LUA_GLOBALSINDEX.intValue(),mainFunction);
//添加參數(數字):
l.pushNumber(7.3);
l.pushNumber(2.7);
//調用方法:
l.call(2,1);//兩個參數一個返回值
//保存返回值:
StringsaveTo="getVarHere";
l.setField(LuaState.LUA_GLOBALSINDEX.intValue(),saveTo);
//獲取返回值:
l.getGlobal(saveTo);
doublepassVar=l.toNumber(-1);
//輸出:
System.out.println(passVar);
//上述代碼針對新手優化,便於理解與入門。下面是我自己實際應用:
Stringcd="functiontest(a,b) returna+b end",
mf="test";
System.out.println(runLua(cd,mf,7.3,2.1).toString());
importorg.keplerproject.luajava.LuaState;
importorg.keplerproject.luajava.LuaStateFactory;
publicstaticobjectrunLua(Stringcode,StringmainFunction,object...par){
LuaStatel=LuaStateFactory.newLuaState();
l.openLibs();
if(l.LdoString(luaCode)!=0)return"Luacodehassomeerror!";
l.getField(LuaState.LUA_GLOBALSINDEX.intValue(),mainFunction);
objectp;for(p:par)l.pushNumber(p);
l.call(par.length,1);
l.setField(LuaState.LUA_GLOBALSINDEX.intValue(),"rt");
l.getGlobal("rt");
returnl.toNumber(-1);
}
❺ lua和java有關系嗎
ava和lua之間進行交互,可是用一種基於jni的luajavaBridge方法,目前已經集成在quick-cocos引擎中了。
luaj的功能整理:
1.lua能夠查找java的方法;
2.lua能夠把函數作為參數傳入到java;
3.lua能夠從java獲得查找調用方法的返回值;
4.java能夠調用lua的函數;
❻ 如何編譯luajava
問題補充:注意:我說的是在lua端如何調用java,而不是在java代碼里調用lualuajava-1.1.dll動態連接庫文件 luajava-1.1.jar就容易了,就是將其加入,HqcrrG
❼ 如何在Java中使用Lua腳本語言
如何在Java中使用Lua腳本語言是本文要介紹的內容,主要是來學習LUA腳本語言在JAVA中如何來使用,Lua就不說了, 現在比較熱門, 語法也很簡單. 為了在Java中調用, 折騰了比較長的時間, 就把一些東西記在下面.來看詳細內容講解。
Lua是支持內嵌在C程序中的, 但是官方不支持Java. 在網上查了下, 有LuaJava開源庫, 拿來試用了一下, 發現這個庫還算比較完善的.
這個LuaJava實際上就是按照Lua官方文檔, 把Lua的C介面通過JNI包裝成Java的庫. 下載, 裡面是一個.dll, 一個.jar. 把.dll放到java.library.path下, 再把.lib放到classpath中, helloworld運行OK.
但是, 測試的時候, 很快發現了第一個問題: 在調用LuaJava中提供的LuaState.pushInteger 方法的時候, 出現了錯誤 : Unsatisfied Link Error. 其他的LuaState.pushNumber方法倒是沒有問題. 用Depends工具看了下, 這個.dll居然沒有導出pushInteger這個函數. 暈....
下載LuaJava的源代碼, 查看了下Luajava.c 和 Luajava.h, 發現果然裡面有點問題, 在.h裡面定義了JNI中對應Java函數的C函數
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger
但是.c中沒有實現這個函數. 無語, 看來大馬虎哪都有啊. 幸虧有源代碼, 照貓畫虎在Luajava.c中加上這個函數的實現,
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger (JNIEnv * env, jobject jobj, jobject cptr, jint i) { lua_State * L = getStateFromCPtr( env , cptr ); lua_pushinteger(L, i); }
然後編譯. 編譯也出現了問題了, 官方文檔中說可以用VC++來Build, 但是沒有說官方用的是什麼版本. 我用VC2005就不行. 好在Luajava比較小, 就一個.h 一個 .c , 在VC中新建一個.dll項目, 把文件加進去, 修改一下build參數 (Include 需要加上lua的頭文件, lib中需要加上lua的.lib文件, 另外要選上 Compile as C Code (/TC) ) Build, 通過了.
這時再在Java中調用pushInteger方法就沒有問題了.
在測試中, 發現Luajava提供的文檔中, 對於Lua腳本怎麼調用Java對象/方法很詳細, 但是在Java中怎麼調用Lua函數/取得返回值 就沒有. 參考了http://www.lua.org/manual/5.1/manual.html#lua_CFunction 的Lua C文檔, 實現了傳遞對象到Lua中並取得返回值的代碼:
Test1: 測試傳遞簡單類型, 並取得返回值:
Lua 腳本(test.lua):
function test(a,b) return a+b end
Java代碼:
static { //載入Lua5.1.dll, 因為LuaJava最後還是要調用Lua的東西 System.loadLibrary("lua5.1"); } public static void main(String[] argu) throws LuaException { LuaState L = LuaStateFactory.newLuaState(); L.openLibs(); //讀入Lua腳本 int error = L.LdoFile("test.lua"); if (error != 0) { System.out.println("Read/Parse lua file error. Exit."); return; } //找到函數test L.getField(LuaState.LUA_GLOBALSINDEX, "test"); //參數1壓棧 L.pushInteger(1); //參數2壓棧 L.pushInteger(2); //調用!! 一共兩個參數, 1個返回值 L.call(2, 1); //保存返回值, 到a中 L.setField(LuaState.LUA_GLOBALSINDEX, "a"); //讀入a LuaObject l = L.getLuaObject("a"); //列印結果. System.out.println("Result is " + l.getString()); L.close(); }
測試2: 傳遞Java對象
class Value { public int i; public void inc() { i++; } public int get() { return i; } public String toString() { return "Value is " + i; } }
Lua腳本: (該腳本中調用兩次對象的inc方法, 並調用get方法輸出結果)
function test1(v) v:inc(); v:inc(); print("In lua: " .. v:get()); return v end
Java 代碼: (前面都一樣, 略)
//找到函數test1 L.getField(LuaState.LUA_GLOBALSINDEX, "test1"); //生成新的對象供測試 Value v = new Value(); //對象壓棧 L.pushObjectValue(v); //調用函數test1, 此時1個參數, 1個返回值 L.call(1, 1); //結果放在b中. L.setField(LuaState.LUA_GLOBALSINDEX, "b"); LuaObject l = L.getLuaObject("b"); System.out.println("Result is " + l.getObject());
運行結果:
Result is Value is 2 In lua: 2
和預期的一致.
實現一個怪物的創建,把lua里的設定當作初始狀態傳給monstor,名字為sample monstor,防禦10,攻擊10,生命100
1.先導入lib--luajava-1.1.jar
import org.keplerproject.luajava.LuaState; import org.keplerproject.luajava.LuaStateFactory; public class Load{ LuaState luaState; /** * Constructor * @param fileName File name with Lua . */ Load(final String fileName) { this.luaState = LuaStateFactory.newLuaState(); this.luaState.openLibs(); this.luaState.LdoFile(fileName); } /** * Ends the use of Lua environment. */ void close() { this.luaState.close(); } /** * Call a Lua inside the Lua to insert * data into a Java object passed as parameter * @param Name Name of Lua . * @param obj A Java object. */ void run(String Name, Object obj) { this.luaState.getGlobal(Name); this.luaState.pushJavaObject(obj); this.luaState.call(1,0); } } public class Monster{ /* Info */ protected String race; protected int defense; protected int attack; protected int life; /* */ private Load ; public Monster(String race) { /* Loads Lua for this race.*/ this. = new Load(race+".lua"); /*Call Lua create .*/ .run("create", this); } public void setRace(String race) { this.race = race; } public String getRace() { return race; } public int getDefense() { return this.defense; } public void setDefense(int defense) { this.defense = defense; } public int getLife() { return this.life; } public void setLife(int life) { this.life = life; } public void setAttack(int attack) { this.attack = attack; } public int getAttack() { return this.attack; } } monstor.lua--- create(monster) monster:setRace("Sample Monster") monster:setDefense(10) monster:setAttack(10) monster:setLife(100) end
但總是拋出這個錯誤:
PANIC: unprotected error in call to Lua API (Invalid method call. No such method.)
不知為何,以後用到的時候再research.
已經查出來,原來在Monster類中少了個方法:
public void setRace(String race) { this.race = race; }
怪不得會找不到,
要在一lua文件a.lua里導入其他的lua文件b.lua,用require "b"
如果要從lua中運算後得到返回參數,則需要做一下修改:在lua文件中改成:
create(monster) monster:setRace("Sample Monster") monster:setDefense(10) monster:setAttack(10) monster:setLife(100) return monster end
在Load.java中的run改成如下:
void run(String Name, Object obj) { this.luaState.getGlobal(Name); this.luaState.pushJavaObject(obj); this.luaState.call(1, 1);// 一個參數,0個返回 try { Object object =luaState.getObjectFromUserdata(1); } catch (LuaException e) { e.printStackTrace(); } }
轉載僅供參考,版權屬於原作者。祝你愉快,滿意請採納哦
❽ lua如何調用java程序
Lua是一個實用的腳本語言,相對於Python來說,比較小巧,但它功能並不遜色,特別是在游戲開發中非常實用(WoW採用的就是Lua作為腳本的)。Lua在C\C++的實現我就不多說了,網上隨便一搜,到處都是這方面的介紹,我想說的是如何在Java下使用Lua以提高編程效率、增強你的程序可擴展性。
首先,要在Java上使用Lua腳本,必須有關於Lua腳本解釋器以及Java程序可以訪問這些腳本的相關API,即相關類庫。我使用的是一個叫做LuaJava的開源項目,可以在: http://www.keplerproject.org/luajava/ 找到LuaJava的類庫以及源代碼,使用文檔資等
下載下來解壓後包括兩個文件(我下載的是1.1版本的): luajava-1.1.jar 文件和 luajava-1.1.dll動態連接庫文件
luajava-1.1.jar就容易了,就是將其加入你的項目的ClassPath中,以便程序可以使用它提供的API
luaJava-1.1.dll就麻煩了,你必須將其加入你的Windows安裝目錄下,比如你用的是XP,安裝在C盤,那就直接將其加入C:\WINDOWS目錄下即可,當然你也可以將其加入你的JDK下的jre下
好了,現在你的項目就可以使用Lua腳本來實現動態擴展功能了!不過不要急,你還得有工具來寫Lua腳本吧?不可能用記事本來寫吧???????
你可以使用UltraEdit,但你用UE打開lua文件後,會發現和記事本差不多,並沒有高亮(可能新版本的支持Lua腳本了),如果你的UE不支持,那麼先去UltraEdit的官網下載支持Lua的Wordfiles文件(http://www.ultraedit.com/files/wf/lua.txt),是個文本文件(lua.txt)。打開UltraEdit安裝目錄下的wordfile.txt,把lua.txt文件中的內容拷貝粘貼到wordfile.txt的末尾,存檔,OK,於是UltraEdit語法高亮項多出Lua一項,可以選擇使用了。其他語言的語法高亮支持與此類似。
但你如果是Java開發者,應該都用過Eclipse吧?可否在Eclipse下直接就寫Lua腳本呢?答案是可以的!
這當然是Eclipse的強大的插件管理功能啦,你可以去下載luaeclipse插件來使你的Eclipse擁有編寫Lua腳本的能力(既可以高亮顯示你的腳本,是不是很爽呢),你可以在這里下載:http://www.ideais.com.br/luaeclipse/
下載後安裝後,你的Eclipse就可以建立和編寫Lua腳本了,注意設置一下首選項中關於LUA的屬性(Eclipse安裝插件就不用我說了吧????)
好了,現在一切都准備好了,讓我們來一個HelloWorld吧!
首先在Eclipse先建立一個TestLua項目,然後編寫如下程序:
import org.keplerproject.luajava.*;
public class Hello
{
public static void main(String[] args)
{
LuaState L = LuaStateFactory.newLuaState();
L.openLibs();
System.out.println("這里是Java程序調用Lua腳本");
// 載入腳本hello.lua,並執行
L.LdoFile("res/hello.lua");
}
}
好了,程序寫完了,當然是保存為Hello.java咯,注意,這是Java代碼!這是Java代碼調用了一個叫hello.lua的腳本,下邊是這個腳本文件的內容(你可以直接把他們復制到你的hello.lua文件中):
================================================================
--基本方法
print("您現在使用的是LUA腳本語言")
print("讓我們一起來感受它的奇妙吧!\n")
--特點1,賦值
a={1,2}
b=a
print(a==b, a~=b) --輸出 true, false
a={1,2}
b={1,2}
print(a==b, a~=b) --輸出 false, true
--特點2,交換
a,b=1,2
a,b=b,a
print(a)
print(b)
print("連接".."字元串"..2^3)
print(type(2))
--while循環
i=0
print("while循環例子")
while i<5
do
print(i);
i=i+1
end
--repeat循環
i=0
print("repeat循環例子")
repeat
print(i)
i=i+1
until i>=5
--for循環
print("for循環例子")
for i=0,5,1
do
print(i)
end
T1={}
T1[1] = 10
print(T1[1])
function fun(a,b,...)
print(a)
print(b)
print(arg[1])
print(arg[2])
print(arg[3])
return
end
a,b=2,3
fun(a,b,200,400,500)
========================================================
好了,上邊的腳本如果你不懂什麼意思也沒關系,直接運行一下吧
你可以執行編譯執行那個Hello.java程序就可以了,就會看到如下的輸出結果:
========================================================
這里是Java程序調用Lua腳本
您現在使用的是LUA腳本語言
讓我們一起來感受它的奇妙吧!
true false
false true
2
1
連接字元串8
number
while循環例子
0
1
2
3
4
repeat循環例子
0
1
2
3
4
for循環例子
0
1
2
3
4
5
10
2
3
200
400
500
==========================================================
怎樣,是不是很爽呢?覺得沒意思?好,在來一段腳本吧:
frame = luajava.newInstance("java.awt.Frame", "Lua Java Console")
console = luajava.newInstance("java.awt.TextArea")
buttons_pn = luajava.newInstance("java.awt.Panel")
execute_bt = luajava.newInstance("java.awt.Button", "Execute")
clear_bt = luajava.newInstance("java.awt.Button", "Clear")
exit_bt = luajava.newInstance("java.awt.Button", "Exit")
frame:setSize(600,300)
buttons_pn:add(execute_bt)
buttons_pn:add(clear_bt)
buttons_pn:add(exit_bt)
BorderLayout = luajava.bindClass("java.awt.BorderLayout")
frame:add(BorderLayout.NORTH, console)
frame:add(BorderLayout.SOUTH, buttons_pn)
frame:pack()
frame:show()
--
-- Listeners
--
execute_cb = {
actionPerformed = function(ev)
print("execute")
pcall(loadstring(console:getText()))
end
}
jproxy = luajava.createProxy("java.awt.event.ActionListener",execute_cb)
execute_bt:addActionListener(jproxy)
clear_cb = {actionPerformed= function (ev)
print("clear");
console:setText("");
end
}
jproxy = luajava.createProxy("java.awt.event.ActionListener" ,clear_cb)
clear_bt:addActionListener(jproxy)
exit_cb = { actionPerformed=function (ev)
print("exit")
frame:setVisible(false)
frame:dispose()
end
}
jproxyb = luajava.createProxy("java.awt.event.ActionListener" ,exit_cb)
exit_bt:addActionListener(jproxyb)
close_cb = { }
function close_cb.windowClosing(ev)
print("close")
frame:setVisible(false)
frame:dispose()
end
function close_cb.windowActivated(ev)
print("act")
end
jproxy = luajava.createProxy("java.awt.event.WindowListener", close_cb)
frame:addWindowListener(jproxy)
這段腳本運行後你將會非常想進一步了解LUA的奧妙,至於什麼我就不說了,你們自己運行看看吧。。。哈哈,就寫到這里了,我去上下WC。。。。
❾ 在java中調用lua執很多次之後,內存使用率持續上升,無法釋放
要看LuaState luaState = LuaStateFactory.newLuaState();
和 luaState.close();的實現方式。
lua中有調用內存分配用戶對象,但沒注冊gc的話,luastate的close不會釋放內存。