我如何将对象传递给一个暴露的luaj函数?

我正在尝试使用Luaj + java构建控制器。我有以下java类

public class Duck {
  public void talk() { System.out.println("Duck quacks!"); }
  public void walk() { System.out.println("Duck walks!"); }
}

public class Person {
  public void talk() { System.out.println("Person talks!"); }
  public void walk() { System.out.println("Person walks!"); }
}

还有以下Lua脚本用于控制器:

onTalk(obj)
  obj:talk();
end

onWalk(obj)
   obj:walk();
end

我理想情况下想定义一个控制器(用Lua编写),其中我将保存所有程序逻辑,并且我想从该控制器中向我的Java代码公开API。我尝试使用以下方法:

ScriptEngineManager sem     = new ScriptEngineManager();
ScriptEngine        engine  = sem.getEngineByExtension(".lua");
ScriptEngineFactory factory = engine.getFactory();

// Script defined above
CompiledScript cs = ((Compilable)engine).compile(MY_LUA_SCRIPT);
SimpleBindings b = new SimpleBindings();

b = newSimpletBindings();

LuaValue onWalkHandler = (LuaValue)b.get("onWalk");
//func.call(LuaValue.valueOf(duck)); // Passing duck object does not work ???

我无法将对象传递给LuaValue。如何将java对象传递给lua脚本?

PS:通常使用Java和嵌入式脚本时,人们将功能捆绑在一个脚本中,还是每个回调都有单独的脚本?

点赞
用户15459
用户15459

我正在搜索luaj 条目并发现了您未回答的问题。您的问题很有趣,让我搜索。然后我意识到这个问题是在两年前提出的……我希望我的答案对其他人有用!基于luaj-3.0-alpha1的代码。

我们需要一个有效的Lua脚本(您忘记了function关键字):

function onTalk(javaObj)
  print(type(javaObj) .. " " .. tostring(javaObj))
  print(javaObj.name)
  javaObj:talk()
  return true
end

function onWalk(javaObj)
  javaObj:walk()
  return 1, "km"
end

我添加了一些跟踪代码... 我还创建了类似于您的类:

class Dog
{
  public String name;
  Dog(String n) { name = n; }
  public void talk() { System.out.println("Dog " + name + " barks!"); }
  public void walk() { System.out.println("Dog " + name + " walks..."); }
}
class Cat
{
  String name;
  Cat(String n) { name = n; }
  public void talk() { System.out.println("Cat " + name + " meows!"); }
  public void walk() { System.out.println("Cat " + name + " walks..."); }
}

添加一个字段以测试这个。对于我的测试,我只是在方法内部声明这些类,创建它们的实例:

Dog dog = new Dog("Rex");
Cat cat = new Cat("Felix");

我首先尝试将这些Java对象转换为Lua,使用LuaValue luaDog = LuaValue.userdataOf(dog);,但它不起作用:我们确实有userdata,如跟踪所示,但没有元表,所以我们无法调用方法或访问字段。

在搜寻了很多后,我找到了正确的咒语:

CompiledScript script = ((Compilable) scriptEngine).compile(reader);
Bindings sb = new SimpleBindings();
script.eval(sb); // 将Lua函数放入sb环境中
LuaValue luaDog = CoerceJavaToLua.coerce(dog); // Java to Lua
LuaFunction onTalk = (LuaFunction) sb.get("onTalk"); // 获取Lua函数
LuaValue b = onTalk.call(luaDog); // 调用函数
System.out.println("onTalk answered: " + b);
LuaFunction onWalk = (LuaFunction) sb.get("onWalk");
LuaValue[] dogs = { luaDog };
Varargs dist = onWalk.invoke(LuaValue.varargsOf(dogs)); // 替代方法
System.out.println("onWalk returned: " + dist);

我很欣赏Luaj API... :-) 对于Java程序员而言,这可能更加方便,而其他库似乎更针对Lua / C程序员...

2012-10-25 16:17:17