Java + Lua = 王炸!!

我們寫東西的時候總會遇到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開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章