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

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

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

3天內不再提示

在Java方法中調用Lua function

工程師鄧生 ? 來源:芋道源碼 ? 作者:芋道源碼 ? 2022-09-07 10:47 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

luaj 主要特征

luaj 用法示例

luaj 實現原理

查找并調用指定的 Java 方法

從 Java 方法獲取返回值

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

在某些業務場景下,我們可能會遇到 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 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

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 動態權限、多租戶、數據權限、工作流、三方登錄、支付、短信、商城等功能

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
    +關注

    關注

    20

    文章

    2988

    瀏覽量

    109396
  • 虛擬機
    +關注

    關注

    1

    文章

    966

    瀏覽量

    29316
  • Lua
    Lua
    +關注

    關注

    0

    文章

    83

    瀏覽量

    10960
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    EtherCAT運動控制卡應用開發教程之Java

    運動控制卡的Java開發及DLL調用
    的頭像 發表于 06-13 14:29 ?214次閱讀
    EtherCAT運動控制卡應用開發教程之<b class='flag-5'>Java</b>

    IAR Arm開發工具鏈--function_sections編譯選項的使用

    本文主要介紹IAR Arm開發工具鏈不修改源代碼的情況下使用??function_sections編譯選項把函數放到單獨的section。
    的頭像 發表于 06-13 13:53 ?1024次閱讀
    <b class='flag-5'>在</b>IAR Arm開發工具鏈<b class='flag-5'>中</b>--<b class='flag-5'>function</b>_sections編譯選項的使用

    ArkUI-X與Android橋接通信之方法回調

    ) => { console.error(\'error: \' + JSON.stringify(err)); }); 2.Android側實現被調用方法。 // xxx.ja
    發表于 06-08 22:16

    ArkUI-XPlugin生命周期開發指南

    ; } } } 添加ArkUI-X插件 StageActivity,新增addPlugin11+方法,并以字符串形式提供IArkUIXPlugin的實現類的完整包名,用于將開發者實現
    發表于 06-04 22:36

    研發排查問題的利器:一款方法調用棧跟蹤工具

    作者:京東物流 郭忠強 導語 本文從日常值班問題排查痛點出發,分析方法復用的調用鏈路和上下文業務邏輯,通過思考分析,借助棧幀開發了一個方法調用棧的鏈式跟蹤工具,便于展示一次請求的
    的頭像 發表于 05-06 17:24 ?2690次閱讀
    研發排查問題的利器:一款<b class='flag-5'>方法</b><b class='flag-5'>調用</b>棧跟蹤工具

    nginx+lua+redis實現灰度發布

    了這種能力,隨時可以基于這種能力和思想調整實現方案:比如nginx+lua+(其他數據源)、nginx+(其他腳本語言) 一、灰度方案: 常見的灰度實現方案: 1.請求路由:通過請求的標識(如用戶ID、設備ID、請求頭等)來決定是否將請求路由到灰度環境。可以使用反向代
    的頭像 發表于 12-17 10:01 ?430次閱讀

    Open開發新方法Lua語言快速學習

    很多朋友都問我不會Lua又想open開發,怎么辦?我的答復是Lua先學起來,再看LuatOS具體應用示例,上手極快,感興趣的朋友們,可以參照本文一起學。
    的頭像 發表于 12-11 09:31 ?528次閱讀
    Open開發新<b class='flag-5'>方法</b>!<b class='flag-5'>Lua</b>語言快速學習

    不會Lua又想Open開發,怎么辦?

    本次我把收藏已久的LuatOS具體應用示例特分享個大家,希望不會Lua又想Open開發的朋友有收獲。
    的頭像 發表于 12-09 14:43 ?495次閱讀
    不會<b class='flag-5'>Lua</b>又想Open開發,怎么辦?

    Java時間戳的使用

    Java時間戳的使用
    的頭像 發表于 11-06 16:04 ?506次閱讀
    <b class='flag-5'>Java</b><b class='flag-5'>中</b>時間戳的使用

    Lua語法基礎教程(下篇)

    今天我們繼續學習Lua語法基礎教程,下篇。 九、函數 9.1 初識函數 函數是指一段在一起的、可以做某一件事兒的程序,也叫做子程序。 在前面的內容,我們已經接觸過了函數的調用,這個函數就是前面用到
    的頭像 發表于 10-26 11:41 ?648次閱讀
    <b class='flag-5'>Lua</b>語法基礎教程(下篇)

    Lua語法基礎教程(中篇)

    今天我們繼續學習Lua語法基礎教程,中篇。 五、變量 5.1 number變量 變量,可以看作是一個桶,在里面裝你想要裝的內容。這些內容可以是Lua包含的所有合法類型。 例如:我想要新建一個桶,名叫
    的頭像 發表于 10-26 11:39 ?728次閱讀
    <b class='flag-5'>Lua</b>語法基礎教程(中篇)

    怎么JAVA確定線性池大小

    JAVA確定線性池大小,分別介紹CPU密集型任務和I/O密集型任務及其處理方法
    的頭像 發表于 10-24 14:02 ?463次閱讀

    Lua語法基礎教程(上篇)

    意味著Lua虛擬機可以很方便的嵌入別的程序里,從而為應用程序提供靈活的擴展和定制功能。而整個Lua虛擬機編譯后僅僅一百余K,經過適當的裁剪還能做到更小,十分適合嵌入式的開發。 同時,目前腳本引擎
    的頭像 發表于 10-24 07:17 ?821次閱讀

    【龍芯2K0300蜂鳥板試用】+3.移植lua到loongarch

    1.Lua簡介 Lua 是一種輕量小巧的腳本語言,用標準C語言編寫并以源代碼形式開放,其設計目的是為了嵌入應用程序,從而為應用程序提供靈活的擴展和定制功能。 Lua 是巴西里約熱內盧
    發表于 08-18 03:31

    華納云:java web和java有什么區別java web和java有什么區別

    的平臺,Java可以用于開發桌面應用程序、移動應用程序、企業級應用程序等。 – Java Web是Java語言Web開發領域的應用,它使用Java
    的頭像 發表于 07-16 13:35 ?1440次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區別
    主站蜘蛛池模板: 麻豆国产一区二区在线观看 | 18满xo影院视频免费体验区 | 美国色综合 | 夭天干天天做天天免费看 | 夭天干天天做天天免费看 | 久久毛片视频 | 欧美激情区 | 免费被视频网站在线观看 | 一级国产特黄aa大片 | 在线观看视频一区二区 | 色综合久久天天综合观看 | 大黄香蕉 | 色爱综合网 | 久久性色 | 新版天堂中文在线8官网 | www.天天操.com| 四虎成人免费观看在线网址 | 国产免费一级在线观看 | 1024你懂的国产在线播放 | 天堂在线视频网站 | 91久久福利国产成人精品 | 插插操操| 色站在线 | 天天躁夜夜躁狠狠躁2021 | 亚洲成网777777国产精品 | 四虎www成人影院观看 | 亚洲一级香蕉视频 | 日韩欧美一卡二区 | 欧美城天堂网 | 国产一区二区三区 韩国女主播 | 天天操天天干天天做 | 亚洲精品视频在线 | 最好看的2019中文字幕免费高清 | 伊人五月婷婷 | 九色福利| 亚洲 另类 在线 欧美 制服 | 久久综合久色欧美婷婷 | 人人福利| 五月婷婷影视 | japanese色系国产在线高清 | 888米奇色狠狠俺去啦 |