LuaJava
一、什么是LuaJava
LuaJava是一个Java脚本工具。该工具的目标是允许用Lua编写的脚本操纵用 Java开发的组件。LuaJava允许使用与访问Lua的本机对象相同的语法从Lua访问Java组件,而不需要任何声明或任何类型的预处理。
LuaJava还允许在Lua中实现任何Java接口,并将其作为参数传递给任何方法,当调用时,Lua中将调动等效函数,并将结果传递会Java。
LuaJava与Lua5.1的许可证相同,也就是说,它可以免费用于学术和商业目的。
二、Maven依赖引用
<!-- https://mvnrepository.com/artifact/party.iroiro.luajava/luajava -->
<dependency>
<groupId>party.iroiro.luajava</groupId>
<artifactId>luajava</artifactId>
<version>4.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/party.iroiro.luajava/lua54 -->
<dependency>
<groupId>party.iroiro.luajava</groupId>
<artifactId>lua54</artifactId>
<version>4.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/party.iroiro.luajava/lua54-platform -->
<!--<dependency>
<groupId>party.iroiro.luajava</groupId>
<artifactId>lua54-platform</artifactId>
<version>4.0.2</version>
<type>pom</type>
</dependency>-->
<dependency>
<groupId>party.iroiro.luajava</groupId>
<artifactId>lua54-platform</artifactId>
<version>4.0.2</version>
<classifier>natives-desktop</classifier>
<scope>runtime</scope>
</dependency>
三、LuaJava包含两组Java API
围绕Lua C API的薄包装。因此,您需要对Lua C API有一些基本的了解。大多数API名称在驼峰命名法中被重命名,去掉lua_或luaL_前缀。
此外,如果您对API(这是Lua5.*版本之间的交叉点)不满意,可以通过Lua#getLuaNatives直接使用 Lua C API绑定。
更加Java话的API。这需要更少的Lua知识。请参阅Java API。
四、支持的Lua版本
支持的Lua版本有:Lua 5.1、Lua 5.2、Lua 5.3、Lua 5.4、LuaJ和LuaJIT。
五、Java API
Java API主要围绕着party.iroiro.luajava.Lua接口和party.iroiro.luajava.value.LuaValue接口设计。
首先,只需要使用以下任何构造函数获取Lua状态:
new Lua51()
new Lua52()
new Lua53()
new Lua54()
new LuaJit()
new LuaJ()
关闭状态:
Lua L = new Lua51();
// Operations
L.close();
// Or
try (Lua J = new Lua51()) {
// Operations
}
默认情况下,Lua状态仅由Java库加载。要使用string、table或coroutine,你需要显式打开这些库:
- openLibraries 打开所有可用库;
- openLibrary 打开指定的库;
要与Lua值交互,可以使用LuaValue接口或直接使用Lua C API绑定:
@Test
public void test(){
try (Lua L = new Lua54()) {
LuaValue[] returnValues = L.eval("return { a = 1 }, 1024, 'my string value'");
assertEquals(3, returnValues.length);
assertEquals(1, returnValues[0].get("a").toInteger());
assertEquals(1024, returnValues[1].toInteger());
assertEquals("my string value", returnValues[2].toString());
}
}
获取全局变量、设置全局变量:
@Test
public void getGlobalVar(){
try(Lua lua = new Lua54()) {
assertEquals("Lua 5.4", lua.get("_VERSION").toString());
LuaValue value = lua.from(1);
lua.set("a", value); // LuaValue
lua.set("b", 2); // Java Integer
lua.set("c", new BigDecimal(3)); // Any Java object
assertEquals(
6,
lua.eval("return a + b + c:longValue()")[0].toInteger()
);
}
}
要从简单的 Java值创建LuaValue,请使用Lua::from(boolean/double/long/String) 或 Lua::fromNull().
@Test
public void getLuaValues() {
try (Lua L = new Lua54()) {
LuaValue value = L.from(1);
L.set("a", value); // LuaValue
L.set("b", 2); // Java Integer
L.set("c", new BigDecimal(3)); // Any Java object
assertEquals(
6,
L.eval("return a + b + c:longValue()")[0].toInteger()
);
}
}
要运行Lua代码并获取返回值,请使用Lua::eval(String)
@Test
public void getEval() {
try (Lua L = new Lua54()) {
L.openLibraries();
LuaValue[] values1 = L.eval("string.sub('abcdefg', 0, 3)");
assertEquals(0, values1.length);
LuaValue[] values2 = L.eval("return string.sub('abcdefg', 0, 3)");
assertEquals("abc", values2[0].toString());
}
}
LuaValues实现了Java Map接口,并允许直接操作Lua tables.
@Test
public void getTable() {
try (Lua L = new Lua54()) {
L.run("t = { text = 'abc', children = { 'a', 'b', 'c' } }");
LuaValue table = L.eval("return t")[0];
// Get-calls return LuaValues.
assertEquals("abc", table.get("text").toString());
LuaValue children = table.get("children");
// Indices are 1-based.
assertEquals("a", children.get(1).toString());
assertEquals(3, children.size());
// Set-calls accept LuaValues or any Java object.
children.set(4, "d");
// Changes are done in the Lua side.
L.run("assert(t.children[4] == 'd')");
}
}
调用lua函数(使用LuaValue::call(…)调用函数并返回 LuaValue):
@Test
public void getLuaValue() {
try (Lua L = new Lua54()) {
L.openLibrary("string");
LuaValue gsub = L.eval("return string.gsub")[0];
LuaValue luaJava = gsub.call("Lua", "a", "aJava")[0];
assertEquals("LuaJava", luaJava.toString());
}
}
使用LuaValue::toProxy创建java代理:
@Test
public void getRunnable() throws InterruptedException {
try (Lua L = new Lua54()) {
LuaValue runnable = L.eval("return { run = function() print('running...') end }")[0];
Runnable r = runnable.toProxy(Runnable.class);
Thread t = new Thread(r);
t.start();
t.join();
}
}
Lua GitHub:https://github.com/gudzpoz/luajava
Lua官方文档:https://gudzpoz.github.io/luajava/
开源SDK:https://github.com/mingyang66/spring-parent