
我們寫東西的時候總會遇到lua中要呼叫java代碼,當然這個用JNI肯定是可以做到的,但是有更加方便的辦法—LuaJavaBridge,
一、luaj 主要特征
* 可以從 Lua 呼叫 Java Class Static Method
* 呼叫 Java 方法時,支持 int/float/boolean/String/Lua function 五種引數型別
* 可以將 Lua function 作為引數傳遞給 Java,并讓 Java 保存 Lua function 的參考
* 可以從 Java 呼叫 Lua 的全域函式,或者呼叫參考指向的 Lua function
luaj 的功能很簡單,但對于集成各種 SDK 來說已經完全滿足需求了,
二、luaj 用法示例
Java 方法原型
public static float getNum(float n) {
return n;
}
local className = "com/qeeplay/frameworks/CheShi"
local method = 'getDisplayWidth'
local n = 10
local args = {
n
}
local _, screenwidth = luaj.callStaticMethod(className, method, args)
三、luaj 實作原理
luaj 的核心目標有兩個:從 Lua 呼叫 Java, 從 Java 呼叫 Lua,
整理出來就是如下幾點
* 查找并呼叫指定的 Java 方法
* 檢查呼叫結果,并從 Java 方法獲取回傳值
* 將 Lua function 作為引數傳遞給 Java 方法
* 在 Java 方法中呼叫 Lua function
推薦一個開源免費的 Spring Boot 最全教程:
https://github.com/javastacks/spring-boot-best-practice
四、查找并呼叫指定的 Java 方法
JNI 提供了 FindClass() 方法用于查找指定的 Class,所以 luaj.callStaticMethod() 的第一個引數就是要呼叫的 Java Class 的完整類名稱(類名稱中的“.”要替換為“/”),
找到指定 Class 后,利用 JNI 的 GetStaticMethodID() 方法就可以找到這個類的指定靜態方法,前提是要提供靜態方法的名稱和簽名,
所謂簽名,就是指Java方法的引數型別和回傳型別定義,例如前面示例代碼中 GameInterface_doBilling() 方法的簽名是 (Ljava/lang/String;ZZI)V ,關于 Java 方法簽名的具體定義,可以參考:JNI Type Signatures,
這里要說的是 luaj 可以根據呼叫引數自動猜測方法簽名所以示例中我們并沒有寫簽名,示例中指定引數
local args = {n}1
luaj 根據這 個引數,會構造出正確的方法簽名,
注意,這里要說的是 Lua 里沒有辦法準確判斷一個數值是整數還是浮點數,所以 luaj 在猜測方法簽名時,假定所有的數值都是浮點數,所以下面呼叫會報錯
public static int getNum(int n) {
return n;
}
local className = "com/qeeplay/frameworks/CheShi"
local method = 'getDisplayWidth'
local n = 10
local args = {
n
}
local _, screenwidth = luaj.callStaticMethod(className, method, args)
這樣是不行的,所以這個時候我們要自己定義簽名,下面給出正確的示例
public static int getNum(int n) {
return n;
}
local className = "com/qeeplay/frameworks/CheShi"
local method = 'getDisplayWidth'
local n = 10
local args = {
n
}
local sig = "(I)I"
local _, screenwidth = luaj.callStaticMethod(className, method, args,sig)
簽名使用“(依次排列的引數型別)回傳值型別”的格式,幾個例子如下:
簽名 解釋
()V 引數:無,回傳值:無
(I)V 引數:int,回傳值:無
(Ljava/lang/String;)Z 引數:字串,回傳值:布林值
(IF)Ljava/lang/String; 引數:整數、浮點數,回傳值:字串12345
這里列出不同型別對應的 Java 簽名字串:
型別名 型別
I 整數,或者 Lua function
F 浮點數
Z 布林值
Ljava/lang/String; 字串
V Void 空,僅用于指定一個 Java 方法不回傳任何值123456
Java 方法里接收 Lua function 的引數必須定義為 int 型別
五、檢查呼叫結果,并從 Java 方法獲取回傳值
uaj 呼叫 Java 方法時,可能會出現各種錯誤,因此 luaj 提供了一種機制讓 Lua 呼叫代碼可以確定 Java 方法是否成功呼叫,
luaj.callStaticMethod() 會回傳兩個值:
* 當成功時,第一個值為 true,第二個值是 Java 方法的回傳值(如果有),
* 當失敗時,第一個值為 false,第二個值是錯誤代碼,
下面的代碼展示了如何檢查回傳結果和獲得回傳值:
java代碼
public static int AddTwoNumbers(final int number1, final int number2) {
return number1 + number2;
}
Lua代碼
local args = {2, 3}
local sig = "(II)I"
local ok, ret = luaj.callStaticMethod(className, "AddTwoNumbers", args, sig)
if not ok then
print("luaj error:", ret)
else
print("ret:", ret)
end
錯誤代碼定義如下:
錯誤代碼 描述
-1 不支持的引數型別或回傳值型別
-2 無效的簽名
-3 沒有找到指定的方法
-4 Java 方法執行時拋出了例外
-5 Java 虛擬機出錯
-6 Java 虛擬機出錯
六、將 Lua function 作為引數傳遞給 Java 方法
Lua 虛擬機中,Lua function 以值的形式保存,但這個值無法直接給 Java 用,所以 luaj 做了一個 Lua function 參考表,當一個 Lua function 傳遞給 Java 時,這個 function 對應的值會被存在參考表中,并獲得一個唯一的參考 ID (整數),Java 代碼拿到這個參考 ID 后,就可以很方便的呼叫該 Lua function 了,
所以Java 方法里接收 Lua function 的引數必須定義為 int 型別,示例:
public static int getNum(int n) {
return n;
}
local function callback(result)
end
local className = "com/qeeplay/frameworks/CheShi"
local method = 'getDisplayWidth'
local args = {
callback
}
local sig = "(I)I"
local _, screenwidth = luaj.callStaticMethod(className, method, args,sig)
著作權宣告:本文為CSDN博主「Vincent__Lee」的原創文章,遵循CC 4.0 BY-SA著作權協議,轉載請附上原文出處鏈接及本宣告,原文鏈接:https://blog.csdn.net/li15225271052/article/details/70148609
近期熱文推薦:
1.1,000+ 道 Java面試題及答案整理(2022最新版)
2.勁爆!Java 協程要來了,,,
3.Spring Boot 2.x 教程,太全了!
4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/538126.html
標籤:Java
