Question

I am stuck with loading java functions so that it can be called from lua file using luaj.

What i currently do is create something like this :

in some_package/aif.java :

package some_package;

public class aif extends TwoArgFunction {

    public aif() {
    }

    @Override
        public LuaValue call(LuaValue modname, LuaValue env) {
        LuaValue library = tableOf();
        library.set("foo", new foo());
        env.set("aif", library);
        return library;
    }

    //the rest contains the implementations of java functions
}

and then in lua file :

require "some_package/aif"
--etc ...

and then in Main.java file :

public static void Main(String[] args) {
    String script = "lib/some_lua_file.lua";
    globals = JsePlatform.standardGlobals();
    LuaValue chunk = globals.loadFile(script);
    chunk.call( LuaValue.valueOf(script) );         
}

this code works , but what i want is that in lua file we dont have to use "require". I have achieved this similarly but in c++ using this line :

luaL_requiref(L, "aif", luaopen_aiflib, 1);

can we do like that in luaj? i tried :

globals.load(new aif());

but gets Exception in thread "main" org.luaj.vm2.LuaError: index expected, got nil (variable env in call function of aif class is nil)

anybody knows how to setup aif as lua libary to use with luaj?

Was it helpful?

Solution 2

I have found the answer after looking at the luaj implementation of Lua library.

i modified my code :

package some_package;

public class aif extends OneArgFunction{

    public aif() {
    }

    @Override
    public LuaValue call(LuaValue env) {
        Globals globals = env.checkglobals();
        LuaTable aif = new LuaTable();
        aif.set("foo", new foo());
        env.set("aif", aif);
        globals.package_.loaded.set("aif", aif);
        return aif;
    }

    //the rest contains the implementations of java functions
}

I code the aif class to TwoArgFunction is because the tutorial said to do so. Now with the above code, no need to require the class in lua file

OTHER TIPS

You can write your MyXArgImpl like the following:

package mypackage;

import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.ZeroArgFunction;

public class MyZeroArgImpl extends ZeroArgFunction {
    public LuaValue call() {
        return valueOf("My Zero Arg Implementation");
    }
}

and then add it to your LUA as the following:

LuaValue globals = JsePlatform.standardGlobals();
globals.get("dofile").call( LuaValue.valueOf(yourScriptfile));
globals.set("callMyFunction", new MyZeroArgImpl());

Now you can call your function inside your LUA script even without require('...'):

print(callMyFunction())

Lets say your script that you are loading has a function "receive_aif"

function receive_aif( aifObj )

    --This is how you can invoke public function associated with aifObj     
    aifObj:someAifFunction()

end

From java, you can pass aif instance as: (This should work with any java object )

aif aifObj = new aif()
LuaValue receive_aif_handle = globals.get("receive_aif");
LuaValue retvals = receive_aif_handle.call( CoerceJavaToLua.coerce( aifObj ) );

I am using similar constructs in my application using "3.0 aplha-2" release

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top