我怀疑我的无知比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()等也是抱怨(他们没有super来覆盖)例如:
@Override
public void run(int id, EventArgs args) throws LuaException
{
LuaClosure script = scripts.get(id);
(必须覆盖超类型)
我假设有一些类似外部Jar的东西,我需要为Lua本身添加到Eclipse中?但是我没有发现任何指令(也就是说,如果LUAJ是Lua的完整java实现,那么我会期待这个接口类也是LUAJ jar的一部分。
在我发现的三个LUAJ罐子中,我只告诉了Eclipse其中一个(JSE,而不是JME或Source)。
答案 0 :(得分:1)
所以,这对我有用。在Android java应用程序中使用Luaj 3.0和eclipse。
1。)从其下载页面下载Luaj zip,并确保将jse jar放入某个已知位置(luaj-jse-3.0.jar)
2.)告诉Eclipse将其添加为外部Jar(右键单击项目,buildPath / configureBuildPath / Libraries / Add External 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()命令执行脚本并获得'require'时,这个类被实例化。在调用do-nothing创建者之后,Luaj使用modName和env调用2 arg methof。然后,您可以将任何想要的东西粘贴到环境中。在这种情况下,我们构建一个LuaTable函数,然后将其粘贴到名为“game”的环境中,然后从lua我们可以调用Java游戏函数,如
无论如何= game.doSomething(some,junk)
虽然您可能希望将所有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命令。我希望这是真的,但我并不介意我的申请中的要求
无论如何,我希望有一天能帮助别人。从2015年3月开始,就像luaj 3.0版一样,这一切都是真的,只有未来才会知道这会产生什么样的误导。后来会发现这一点。