在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Java與lua互相調用簡單教程

倩倩 ? 來源:芋道源碼 ? 作者:芋道源碼 ? 2022-09-07 10:47 ? 次閱讀

在某些業務場景下,我們可能會遇到 lua 中要調用 java 代碼情況,當然這個用 JNI 肯定是可以做到的,但是有更加方便的辦法:LuaJavaBridge(LuaJava)和 LuaJ。

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 來說已經完全滿足需求了。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

luaj 用法示例

Java 方法原型:

publicstaticfloatgetNum(floatn){
returnn;
}

lua 調用示例:

--Java類的名稱
localclassName="com/xttblog/Test"
--調用的Java方法名
localmethod='getNum'
--調用Java方法需要的參數
localn=10
localargs={
n
}
--調用Java方法
local_,testStaticMethod=luaj.callStaticMethod(className,method,args)

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的后臺管理系統 + 用戶小程序,支持 RBAC 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://gitee.com/zhijiantianya/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

luaj 實現原理

luaj 的核心目標有兩個:從 Lua 調用 Java, 從 Java 調用 Lua。整理出來就是如下幾點

  • 查找并調用指定的 Java 方法
  • 檢查調用結果,并從 Java 方法獲取返回值
  • 將 Lua function 作為參數傳遞給 Java 方法
  • 在 Java 方法中調用 Lua function

查找并調用指定的 Java 方法

JNI 提供了 FindClass() 方法用于查找指定的 Class,所以 luaj.callStaticMethod() 的第一個參數就是要調用的 Java Class 的完整類名稱(類名稱中的“.”要替換為“/”)

找到指定 Class 后,利用 JNI 的 GetStaticMethodID() 方法就可以找到這個類的指定靜態方法,前提是要提供靜態方法的名稱和簽名。

所謂簽名,就是指Java方法的參數類型和返回類型定義。方法的簽名就是類似(Ljava/lang/String;ZZI)V這樣的一串描述,通過字節碼方式可以查看,如下示例:

34c3e5bc-2e57-11ed-ba43-dac502259ad0.png

關于 Java 方法簽名的具體定義,可以參考:JNI Type Signatures

這里要說的是 luaj 可以根據調用參數自動猜測方法簽名所以示例中我們并沒有寫簽名。

示例中指定參數:

localargs={n}

luaj 根據這 個參數,會構造出正確的方法簽名。

注意:這里要說的是 Lua 里沒有辦法準確判斷一個數值是整數還是浮點數,所以 luaj 在猜測方法簽名時,假定所有的數值都是浮點數。所以下面調用會報錯:

publicstaticintgetNum(intn){
returnn;
}

--Java類的名稱
localclassName="com/xttblog/Test"
--調用的Java方法名
localmethod='getNum'
--調用Java方法需要的參數
localn=10
localargs={
n
}
--調用Java方法
local_,testStaticMethod=luaj.callStaticMethod(className,method,args)

這樣是不行的,所以這個時候我們要自己定義簽名。

下面給出正確的示例

publicstaticintgetNum(intn){
returnn;
}
--Java類的名稱
localclassName="com/xttblog/Test"
--調用的Java方法名
localmethod='getNum'
--調用Java方法需要的參數
localn=10
localargs={
n
}
--定義簽名--參數:[I]nteger--返回值:[I]nt
localsig="(I)I"
--調用Java方法
local_,testStaticMethod=luaj.callStaticMethod(className,method,args,sig)

簽名使用“(依次排列的參數類型)返回值類型”的格式,幾個例子如下:

簽名解釋
()V 參數:無,返回值:無
(I)V 參數:int,返回值:無
(Ljava/lang/String;)Z 參數:字符串,返回值:布爾值
(IF)Ljava/lang/String;參數:整數、浮點數,返回值:字符串

這里列出不同類型對應的 Java 簽名字符串:

類型名類型
I整數,或者Luafunction
F浮點數
Z布爾值
Ljava/lang/String;字符串
VVoid空,僅用于指定一個Java方法不返回任何值

Java 方法里接收 Lua function 的參數必須定義為 int 類型

從 Java 方法獲取返回值

luaj 會檢查調用結果,并從 Java 方法獲取返回值。

luaj 調用 Java 方法時,可能會出現各種錯誤,因此 luaj 提供了一種機制讓 Lua 調用代碼可以確定 Java 方法是否成功調用。

luaj.callStaticMethod()會返回兩個值:

  • 當成功時,第一個值為 true,第二個值是 Java 方法的返回值(如果有)。
  • 當失敗時,第一個值為 false,第二個值是錯誤代碼。

下面的代碼展示了如何檢查返回結果和獲得返回值:

publicstaticintAddTwoNumbers(finalintnumber1,finalintnumber2){
returnnumber1+number2;
}

Lua代碼

localargs={2,3}
localsig="(II)I"
localok,ret=luaj.callStaticMethod(className,"AddTwoNumbers",args,sig)

ifnotokthen
print("luajerror:",ret)
else
print("ret:",ret)--輸出ret:5
end

錯誤代碼定義如下:

錯誤代碼描述
-1不支持的參數類型或返回值類型
-2無效的簽名
-3沒有找到指定的方法
-4Java方法執行時拋出了異常
-5Java虛擬機出錯
-6Java虛擬機出錯

將 Lua function 作為參數傳遞給 Java 方法

Lua 虛擬機中,Lua function 以值的形式保存。但這個值無法直接給 Java 用,所以 luaj 做了一個 Lua function 引用表。當一個 Lua function 傳遞給 Java 時,這個 function 對應的值會被存在引用表中,并獲得一個唯一的引用 ID (整數)。Java 代碼拿到這個引用 ID 后,就可以很方便的調用該 Lua function 了。

所以 Java 方法里接收 Lua function 的參數必須定義為 int 類型。

示例:

publicstaticintgetNum(intn){
returnn;
}

localfunctioncallback(result)
---方法內容
end
--Java類的名稱
localclassName="com/xttblog/Test"
--調用的Java方法名
localmethod='getNum'
--調用Java方法需要的參數
localargs={
callback
}
--定義簽名--參數:[I]nteger--返回值:[I]nt
localsig="(I)I"
--調用Java方法
local_,testStaticMethod=luaj.callStaticMethod(className,method,args,sig)

另外,LuaJ 也很好用。只需引入 pom。

34ff6182-2e57-11ed-ba43-dac502259ad0.png

?然后直接把 lua 代碼當做 String 字符串內嵌到 Java 代碼中:

StringluaStr="print'hello,world!'";
Globalsglobals=JsePlatform.standardGlobals();
LuaValuechunk=globals.load(luaStr);
chunk.call();

也可以創建一個 login.lua 腳本,內容如下:

--無參函數
functionhello()
print'hello'
end
--帶參函數
functiontest(str)
print('datafromjavais:'..str)
return'haha'
end

然后,Java先載入login.lua腳本并編譯,然后再獲取指定名稱的函數,無參的直接使用call()方法調用,帶參的需要通過invoke(LuaValue[])傳入參數表:

StringluaPath="res/lua/login.lua";//lua腳本文件所在路徑
Globalsglobals=JsePlatform.standardGlobals();
//加載腳本文件login.lua,并編譯
globals.loadfile(luaPath).call();
//獲取無參函數hello
LuaValuefunc=globals.get(LuaValue.valueOf("hello"));
//執行hello方法
func.call();
//獲取帶參函數test
LuaValuefunc1=globals.get(LuaValue.valueOf("test"));
//執行test方法,傳入String類型的參數參數
Stringdata=func1.call(LuaValue.valueOf("I'amfromJava!")).toString();
//打印lua函數回傳的數據
Logger.info("datareturnfromluais:"+data);

運行結果如下:

hello
datafromjavais:I'amfromJava!
八月07,2022525下午com.tw.login.tools.Loggerinfo
信息: lua return data:haha
350b36b0-2e57-11ed-ba43-dac502259ad0.png

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2973

    瀏覽量

    104947
  • 函數
    +關注

    關注

    3

    文章

    4344

    瀏覽量

    62864
  • 代碼
    +關注

    關注

    30

    文章

    4819

    瀏覽量

    68881

原文標題:Java與lua互相調用簡單教程

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    LabVIEW如何調用Java程序的問題

    本帖最后由 chaosid 于 2013-10-19 02:23 編輯 LabVIEW的互連接口面板中有.NET的函數調用節點,但如何調用Java程序類庫呢?真誠求教各位高手,有思路也行,有
    發表于 10-19 02:19

    Lua腳本簡單介紹

    Lua簡單介紹Lua[1]是一個小巧的腳本語言。作者是巴西人。該語言的設計目的是為了嵌入應用程序中,從而為應用程序提供靈活的擴展和定制功能。Lua腳本能夠非常easy的被C/C++ 代
    發表于 08-20 06:37

    Lua腳本簡單介紹

    Lua簡單介紹Lua[1]是一個小巧的腳本語言。作者是巴西人。該語言的設計目的是為了嵌入應用程序中,從而為應用程序提供靈活的擴展和定制功能。Lua腳本能夠非常easy的被C/C++ 代
    發表于 08-20 08:06

    Lua簡單介紹

    Lua簡單介紹Lua[1]是一個小巧的腳本語言。作者是巴西人。該語言的設計目的是為了嵌入應用程序中,從而為應用程序提供靈活的擴展和定制功能。Lua腳本能夠非常easy的被C/C++代碼
    發表于 08-20 07:47

    如何用java映射創建java對象和調用java對象呢

    java是一種解析語言,java程序是通過java虛擬機解析.class的方式運行起來。因此,java中就存在java映射的概念。下面介紹如
    發表于 04-11 14:43

    如何用java映射創建java對象和調用java對象的方法

    java是一種解析語言,java程序是通過java虛擬機解析.class的方式運行起來。因此,java中就存在java映射的概念。一、首先我
    發表于 07-28 16:11

    EPS8266和Lua遇到PANIC:調用Lua API時出現未受保護的錯誤...”是怎么回事?

    ) 我收到一個錯誤:“PANIC:調用 Lua API 時出現未受保護的錯誤...” 文檔說調用 stop 時 tmr 仍處于注冊狀態。 調用 tmr.state(0) 也是一樣的。
    發表于 04-27 06:18

    Programming in Lua 3ed

    Lua語言的編程學習手冊。Lua是一個小巧的腳本語言。Lua腳本可以很容易的被C/C++ 代碼調用,也可以反過來調用C/C++的函數,這使得
    發表于 10-26 17:21 ?11次下載

    Java調用window的matlab遇到的問題和解決方案

    Java調用window的matlab遇到的問題和解決方案
    的頭像 發表于 06-20 09:32 ?3369次閱讀
    <b class='flag-5'>Java</b>:<b class='flag-5'>調用</b>window的matlab遇到的問題和解決方案

    調用Lua新建的WEB服務器 操作Nodemcu esp8266 控制繼電器實現物聯網

    調用Lua新建的WEB服務器 操作Nodemcu esp8266 控制繼電器實現物聯網
    發表于 12-08 16:51 ?13次下載
    <b class='flag-5'>調用</b><b class='flag-5'>Lua</b>新建的WEB服務器  操作Nodemcu esp8266 控制繼電器實現物聯網

    Java方法中調用Lua function

    Java先載入login.lua腳本并編譯,然后再獲取指定名稱的函數,無參的直接使用call()方法調用,帶參的需要通過invoke(LuaValue[])傳入參數表。
    的頭像 發表于 09-07 10:47 ?1445次閱讀

    微服務架構中的服務之間如何互相調用呢?

    在微服務架構中,需要調用很多服務才能完成一項功能。服務之間如何互相調用就變成微服務架構中的一個關鍵問題。
    的頭像 發表于 01-31 09:46 ?2246次閱讀

    java上位機開發(c庫調用)

    所有的動態語言,包括在java在內,一般都會提供一個調用c庫的方法。java語言的出現是在上個世紀90年代,而c/c++出現的時間要更早 一點,大約提前了20多年,所以在這過程當中積累了很多的資源
    發表于 05-09 10:00 ?0次下載
    <b class='flag-5'>java</b>上位機開發(c庫<b class='flag-5'>調用</b>)

    如何用Rust通過JNI和Java進行交互

    近期工作中有Rust和Java互相調用需求,這篇文章主要介紹如何用Rust通過JNI和Java進行交互,還有記錄一下開發過程中遇到的一些坑。
    的頭像 發表于 10-17 11:41 ?815次閱讀

    shell調用java并返回執行結果

    在Shell腳本中調用Java程序并獲取執行結果,可以通過以下步驟實現: 編寫Java程序:首先,你需要編寫一個Java程序,包含你想要執行的功能。確保你的
    的頭像 發表于 11-08 10:32 ?1827次閱讀
    主站蜘蛛池模板: 屁屁影院在线| 国产亚洲papapa| 一区在线视频| 日日天天夜夜| 1024视频色版在线网站| 福利片免费一区二区三区| 美女很黄很黄是免费的·无遮挡网站| 日本美女中出| 久久青草精品一区二区三区| 国产乱码精品一区二区三 | 欧美黄色片在线| 干干操| 久久天天操| 最新欧美伦理网| 2019天天爱天天做| 很黄网站| 好大好猛好爽好深视频免费| 亚洲先锋资源| 亚洲无卡| 亚洲天堂成人在线| 日日艹| 色婷婷狠狠| 日韩在线视频一区| 黄网站免费大全| 天天摸天天碰天天碰| 天天爱夜夜| www.九色视频| 男男憋尿play按小腹| 日本不卡视频| 好紧好爽太大了h视频| 激情五月社区| 国产成人无精品久久久久国语| 午夜日本一区二区三区| 欧美成人一区二区三区在线电影| 国产麻豆成人传媒免费观看| 天堂在线网站| 国产精品嫩草影院人体模特| 1024你懂的在线观看| 康熙古代高h细节肉爽文全文| 色午夜视频| 毛片色毛片18毛片美女|