2016-07-19 14 views
2

Ich möchte eine Instanz einer Java-Klasse als Userdata zu meinem Lua-Skript zurückgeben. Wäre es möglich, von lua aus auf Eigenschaften und Funktionen dieser Instanz zuzugreifen?Ist es möglich, auf Eigenschaften und Funktionen von userdata zuzugreifen?

Wie so

local car = Car.getNew() 
print(car.hasHonked) 
car:honk() 
print(car.hasHonked) 

Das ist mein Versuch, das Problem

Java (verkürzt)

public class CarModule extends TwoArgFunction { 

    String moduleName = "Car"; 

    public LuaValue call(LuaValue modname, LuaValue env) { 
     LuaValue library = new LuaTable(); 
     library.set("getNew", new getNew()); 
     env.set(moduleName, library); 
     return library; 
    } 

    static class getNew extends ZeroArgFunction { 
     @Override 
     public LuaValue call() { 
      return LuaValue.userdataOf(new Car()); 
     } 
    }  
} 

public class Car { 
    private int count; 

    @Override 
    public String toString() { 
     return "Hello World"; 
    } 

    public void honk() { 
     count++; 
    } 

    public int getHonks() { 
     return count; 
    } 
} 

lua

local car = Car.getNew() 
print(car) -- [email protected] 
print(type(car)) -- = userdata 
print(car.honk) -- = nil 
print(car.getHonks) -- = nil 
print(car:honk) -- = LuaError: function arguments expected 
print(car:getHonks) -- = LuaError: function arguments expected 
print(tostring(car)) -- = Hello World 
car:honk() -- = LuaError: attempt to call nil 
car:getHonks() -- = LuaError: attempt to call nil 
zu lösen

Edit:

die Antwort gefunden here

Statt

return LuaValue.userdataOf(new Car()); 

I

return CoerceJavaToLua.coerce(new Car()); 

Antwort

1

Sie versuchen, den Zugriff auf car.hasHonked auf eine Funktion, die zurückgibt, kann verwenden verlinken Wert von Java. Ich habe luaj nicht benutzt, also kann ich nicht sagen, wie genau das gemacht werden würde, aber hier ist das gleiche Prinzip wie bei lua. Sie müssen lediglich die Funktion __index durch etwas ersetzen, das auf Ihre Variablen zugreift. Der Code verwendet Metatabellen, um die Verknüpfung nicht gefundener Schlüssel mit einer Funktion zu ermöglichen.

Car = {} 
function Car.__index(table, key) 
    print(Car, table, key) 
    return "the java value according to key" 
end 
function Car.getNew() 
    return setmetatable({}, Car) -- sets metatable for userdata or table 
end 

local car = Car.getNew() 

print(car.hasHonked) 
-- prints: 
-- table: 0xa64f80 table: 0xa6e370 hasHonked 
-- the java value according to key 

Eine andere Option könnte nur Funktionen direkt wie folgt verwenden. Diese Funktionen würden zu Java aufrufen und den tatsächlichen Java-Wert zurückgeben.

car = {} 
function car.getHonked() 
    return "the java value" 
end