【问题标题】:How can I pass objects to an exposed luaj function?如何将对象传递给暴露的 luaj 函数?
【发布时间】:2012-09-03 16:40:48
【问题描述】:

我正在尝试使用 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 编写),我将在其中保留所有程序的逻辑,并且我想将该控制器的 API 公开给我的 java 代码。我试图使用以下方法:

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 和嵌入式脚本时,人们是把函数捆绑在一个脚本中,还是每个回调都有一个单独的脚本?

【问题讨论】:

    标签: java lua callback luaj


    【解决方案1】:

    我正在搜索 条目,发现您没有得到答复。你的问题很有趣,让我搜索。然后我意识到它是在 2 年前被问到的......我希望我的回答对其他人有用!基于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");
    

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

    找了好久,终于找到了正确的咒语:

    CompiledScript script = ((Compilable) scriptEngine).compile(reader);
    Bindings sb = new SimpleBindings();
    script.eval(sb); // Put the Lua functions into the sb environment
    LuaValue luaDog = CoerceJavaToLua.coerce(dog); // Java to Lua
    LuaFunction onTalk = (LuaFunction) sb.get("onTalk"); // Get Lua function
    LuaValue b = onTalk.call(luaDog); // Call the function
    System.out.println("onTalk answered: " + b);
    LuaFunction onWalk = (LuaFunction) sb.get("onWalk");
    LuaValue[] dogs = { luaDog };
    Varargs dist = onWalk.invoke(LuaValue.varargsOf(dogs)); // Alternative
    System.out.println("onWalk returned: " + dist);
    

    我很欣赏 Luaj API...:-) 可能更适合 Java 程序员,而其他库似乎更针对 Lua / C 程序员...

    【讨论】:

    • 天哪,这是黄金。谢谢。
    猜你喜欢
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2010-12-01
    • 2010-12-05
    • 2018-06-19
    • 2011-09-14
    • 2021-01-17
    相关资源
    最近更新 更多