震惊,Java+ lua = 王炸
可以从 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;
}
-- Java 类的名称
local className = "com/xttblog/Test"
-- 调用 的Java 方法名
local method = 'getNum'
-- 调用 Java 方法需要的参数
local n = 10
local args = {
n
}
-- 调用 Java 方法
local _, testStaticMethod = luaj.callStaticMethod(className, method, args)
luaj 实现原理
查找并调用指定的 Java 方法 检查调用结果,并从 Java 方法获取返回值 将 Lua function 作为参数传递给 Java 方法 在 Java 方法中调用 Lua function
JNI 提供了 FindClass() 方法用于查找指定的 Class,所以 luaj.callStaticMethod() 的第一个参数就是要调用的 Java Class 的完整类名称(类名称中的“.”要替换为“/”)。
找到指定 Class 后,利用 JNI 的 GetStaticMethodID() 方法就可以找到这个类的指定静态方法,前提是要提供静态方法的名称和签名。
所谓签名,就是指Java方法的参数类型和返回类型定义。方法的签名就是类似(Ljava/lang/String;ZZI)V这样的一串描述,通过字节码方式可以查看,如下示例:
local args = {n}
public static int getNum(int n) {
return n;
}
-- Java 类的名称
local className = "com/xttblog/Test"
-- 调用 的Java 方法名
local method = 'getNum'
-- 调用 Java 方法需要的参数
local n = 10
local args = {
n
}
-- 调用 Java 方法
local _, testStaticMethod = luaj.callStaticMethod(className, method, args)
public static int getNum(int n) {
return n;
}
-- Java 类的名称
local className = "com/xttblog/Test"
-- 调用 的Java 方法名
local method = 'getNum'
-- 调用 Java 方法需要的参数
local n = 10
local args = {
n
}
-- 定义签名-- 参数: [I]nteger-- 返回值: [I]nt
local sig = "(I)I"
-- 调用 Java 方法
local _, testStaticMethod = luaj.callStaticMethod(className, method, args,sig)
签名 解释
()V 参数:无,返回值:无
(I)V 参数:int,返回值:无
(Ljava/lang/String;)Z 参数:字符串,返回值:布尔值
(IF)Ljava/lang/String; 参数:整数、浮点数,返回值:字符串
类型
I 整数,或者 Lua function
F 浮点数
Z 布尔值
字符串
V Void 空,仅用于指定一个 Java 方法不返回任何值
从 Java 方法获取返回值
当成功时,第一个值为 true,第二个值是 Java 方法的返回值(如果有)。 当失败时,第一个值为 false,第二个值是错误代码。
public static int AddTwoNumbers(final int number1, final int number2) {
return number1 + number2;
}
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) -- 输出 ret: 5
end
错误代码 描述
-1 不支持的参数类型或返回值类型
-2 无效的签名
-3 没有找到指定的方法
-4 Java 方法执行时抛出了异常
-5 Java 虚拟机出错
-6 Java 虚拟机出错
public static int getNum(int n) {
return n;
}
local function callback(result)
---方法内容
end
-- Java 类的名称
local className = "com/xttblog/Test"
-- 调用 的Java 方法名
local method = 'getNum'
-- 调用 Java 方法需要的参数
local args = {
callback
}
-- 定义签名-- 参数: [I]nteger-- 返回值: [I]nt
local sig = "(I)I"
-- 调用 Java 方法
local _, testStaticMethod = luaj.callStaticMethod(className, method, args,sig)
String luaStr = "print 'hello,world!'";
Globals globals = JsePlatform.standardGlobals();
LuaValue chunk = globals.load(luaStr);
chunk.call();
--无参函数
function hello()
print 'hello'
end
--带参函数
function test(str)
print('data from java is:'..str)
return 'haha'
end
String luaPath = "res/lua/login.lua"; //lua脚本文件所在路径
Globals globals = JsePlatform.standardGlobals();
//加载脚本文件login.lua,并编译
globals.loadfile(luaPath).call();
//获取无参函数hello
LuaValue func = globals.get(LuaValue.valueOf("hello"));
//执行hello方法
func.call();
//获取带参函数test
LuaValue func1 = globals.get(LuaValue.valueOf("test"));
//执行test方法,传入String类型的参数参数
String data = func1.call(LuaValue.valueOf("I'am from Java!")).toString();
//打印lua函数回传的数据
Logger.info("data return from lua is:"+data);
hello
data from java is:I'am from Java!
八月 07, 2022 5:31:25 下午 com.tw.login.tools.Logger info
信息: lua return data:hah
评论