我怀疑我的无知远不只是LUAJ,所以请保持温柔。

目标:在我的应用程序中定期运行lua脚本,并在一定程度的安全性下在Lua和Java之间来回传递数据(例如,不要让lua删除文件)

我的大多数应用程序都是直接的android / java,并且运行良好。在这种情况下,我不是白痴。

通过各种示例进行工作,我终于将LUAJ Jar文件作为外部Jar进入了Eclipse。在那之后,这些进口工作了

import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import org.luaj.vm2.lib.jse.JsePlatform;


而且大多数代码都在很大程度上进行编译,但是在此行中,我仍然没有“ Lua”接口可用于此行:

public class MyLuaEngine  implements Lua


该行失败,因为“因为Lua不是超类,所以无法实现”。我很确定它不知道Lua是什么(除非它在其他名称空间或其他名称中找到一个关联)。

另外,我对Lua:add()等的替代也抱怨(没有超级替代),例如:

@Override
public void run(int id, EventArgs args) throws LuaException
{
    LuaClosure script = scripts.get(id);


(必须覆盖超类型)

我假设需要为Lua本身向Eclipse中添加诸如外部Jar之类的东西,但是我没有找到执行此操作的说明(此外,如果LUAJ是Lua的完整Java实现,那么我希望这个接口类也将成为LUAJ jar的一部分。

在我发现的三个LUAJ jar中,我只告诉了Eclipse其中一个(JSE,而不是JME或Source)。

最佳答案

所以,这是对我有用的。在Android Java应用程式中使用Luaj 3.0和eclipse。

1.)从其下载页面下载Luaj zip,并确保将jse jar放入某个已知位置(luaj-jse-3.0.jar)

2.)告诉Eclipse将其添加为外部Jar(右键单击项目,buildPath / configureBuildPath / Libraries /添加外部Jar

3.)添加这些导入

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.jse.JsePlatform;


(以及其他需要的东西,但是可以从这些类路径中获取。只要您有jar文件,Eclipse ctrl-shift-O都可以解决)

4.)一些示例用法(luaj将打印文本发送到android logcat)

void testLua()
{
    //-----
    // Simple Test Lua Script

    String myScript = "require 'com.Your.Class.Path.Here.GameFunctions' \n"
                    + " \n"
                    + "print 'hello, world from lua' \n"
                    + "print( game.testFunction( 5 ) ) \n"
                    + " \n"
                    + "function foo() \n"
                    + "  print( 'You have been fooed!' ) \n"
                    + "end \n"
                    + " \n"
                    + "function foo2( a, b ) \n"
                    + "  print( 'Foo2 got '.. a ..', and '.. b ..' !' ) \n"
                    + "end \n"
                    + " \n"
                    + "function foo3( a, b ) \n"
                    + "  print( 'Foo3 got '.. a ..', and '.. b ..' !' ) \n"
                    + "  return 'fantastic!' \n"
                    + "end \n"
                    + " \n"
                    + "print 'Good bye from my lua program' \n"
                    + ""
                    ;
     // Create the globals object and initialize with standard stuff
    Globals globals = JsePlatform.standardGlobals();

     // Load (and compile?) the simple script and get a Chunk
    LuaValue chunk = globals.load( myScript );

     // run the script once from the beginning (root level)
    chunk.call();

     // run it a second time, just to see if it blows up, and
     // get the return value, if any. (didnt blow up)
    LuaValue result = chunk.call();

    // try to call a specific function, no args
    LuaValue foo = globals.get( "foo" );    // get the function to call as a LuaValue
    if( !foo.isnil() ) {
        foo.call();   // runs just that function
    }

    LuaValue foo2 = globals.get( "foo2" );  // pass two args
    if( !foo2.isnil() ) {
        foo2.call(  LuaValue.valueOf("first"),
                    LuaValue.valueOf("second") );
    }

    LuaValue foo3 = globals.get( "foo3" );  // pass 2 args, get 1 back
    if( !foo3.isnil() ) {
        LuaValue retVal = foo3.call(    LuaValue.valueOf("first"),
                                        LuaValue.valueOf("second") );
        Log.v( TAG, "LUA: foo3 returned: " + retVal.toString() );
    }


}

lua脚本的第一行是require命令,它调用到我称为GameFunctions的公共类的完整类路径。它是lua可以通过该接口调出感兴趣的自定义Java函数(例如,获取玩家的乐谱,播放声音效果等)的接口。

我的Bare Bones实现看起来像这样:(非常感谢所有对此做出贡献的网页,尽管最终我只是猜测2 arg调用将具有modName和env)

当.load()脚本字符串时,将对其进行编译,并且返回LuaValue(块)是已编译的代码。但是您不能在块上使用.get(“ functionName”),而必须使用'globals'对象(这很有意义,但需要及时编译才能使我的头稍微旋转一下,我觉得这发生在,load(),但是我想留下一些符号表供全局变量以后使用。

无论如何,该类将在.call()命令执行脚本并进入“需要”的时刻实例化。调用无所事事的创建者后,Luaj调用带有modName和env的2 arg methof。然后,您可以将任何所需的东西粘贴到环境中。在这种情况下,我们构建函数的LuaTable,然后将其以“ game”的名称粘贴到环境中,然后从lua中我们可以调用Java游戏函数,例如

无论= game.doSomething(一些,垃圾)

尽管您可能希望将所有lua放在单独的线程中,以免UI停滞。我希望Lua调试钩子存在于某处,以便我可以限制播放器提供的无限循环的执行时间:-)

public class GameFunctions extends TwoArgFunction {
private static final String TAG = GameFunctions.class.getSimpleName();

public GameFunctions() {
}

public LuaValue call( LuaValue modname, LuaValue env )
{
    Log.v( TAG, "LUA: modName: " + modname.toString()
            + ", Env: " + env.toString() );

    LuaTable game = new LuaTable();

    // the actual functions get added to game table
    game.set("testFunction", new testFunction());

    // we set it into the environment so lua can see them
    env.set("game", game);

    // we mark it so no 'require' is needed
    env.get("package").get("loaded").set("game", game);

    return game;
}

// An example Game Function... not a very good one.  Pretend
// it plays a sound effect.  I just wanted to test arg passing
// don't forget to convert to LuaValues as needed.

class testFunction extends OneArgFunction {
    public LuaValue call(LuaValue x) {
        return LuaValue.valueOf( "you said: " + x );
    }
}


}

从理论上讲,末尾的位使不必在脚本中包含require命令。我希望这是真的,但是我真的不介意我的应用程序中的需求

无论如何,我希望有一天能对其他人有所帮助。从luaj 3.0版开始,这一切在2015年3月就已经足够了,只有未来知道这种误导性会在以后出现。

关于android - 尝试在Android应用中使用LUAJ,找不到类Lua,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29313178/

10-11 15:06