如何在Java中使用Lua脚本语言

java代码,执行lua脚本!~

要在Java上使用Lua脚本,必须有关于Lua脚本解释器以及Java程序可以访问这些脚本的相关API,即相关类库。可以使用一个叫做LuaJava的开源项目,可以在www.keplerproject.org/luajava/ 找到LuaJava的类库以及源代码,使用文档资等

LuaJava实际上就是按照Lua官方文档, 把Lua的C接口通过JNI包装成Java的库. 下载, 里面是一个.dll, 一个.jar. 把.dll放到java.library.path 下, 再把.lib放到classpath 中, helloworld运行OK.但是, 测试的时候, 很快发现了第一个问题: 在调用LuaJava中提供的LuaState.pushInteger 方法的时候, 出现了错误 : Unsatisfied Link Error . 其他的LuaState.pushNumber 方法倒是没有问题. 用Depends工具看了下, 这个.dll居然没有导出pushInteger 这个函数。(1).下载LuaJava的源代码, 查看了下Luajava.c 和 Luajava.h, 发现果然里面有点问题, 在.h里面定义了JNI中对应Java函数的C函数JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger 但是.c中没有实现这个函数. 无语, 看来大马虎哪都有啊. 幸亏有源代码, 照猫画虎在Luajava.c中加上这个函数的实现,

(2).然后编译. 编译也出现了问题了, 官方文档中说可以用VC++来Build, 但是没有说官方用的是什么版本. 我用VC2005就不行. 好在Luajava比较小, 就一个.h 一个 .c , 在VC中新建一个.dll项目, 把文件加进去, 修改一下build参数 (Include 需要加上lua的头文件, lib中需要加上lua的.lib文件, 另外要选上 Compile as C Code (/TC) ) Build, 通过了.这时再在Java中调用pushInteger方法就没有问题了.在测试中, 发现Luajava提供的文档中, 对于Lua脚本怎么调用Java对象/方法很详细, 但是在Java中怎么调用Lua函数/取得返回值 就没有. 参考了http://www.lua.org/manual/5.1/manual.html#lua_CFunction 的Lua C文档, 实现了传递对象到Lua中并取得返回值的代码:Test1: 测试传递简单类型, 并取得返回值:Lua 脚本(test.lua):
function test(a,b)return a+bend Java代码:static {//加载Lua5.1.dll, 因为LuaJava最后还是要调用Lua的东西System.loadLibrary("lua5.1");}public static void main(String[] argu) throws LuaException {LuaState L = LuaStateFactory.newLuaState();L.openLibs();//读入Lua脚本int error = L.LdoFile("test.lua");if (error != 0) {System.out.println("Read/Parse lua file error. Exit.");return;}//找到函数testL.getField(LuaState.LUA_GLOBALSINDEX, "test");//参数1压栈L.pushInteger(1);//参数2压栈L.pushInteger(2);//调用!! 一共两个参数, 1个返回值L.call(2, 1);//保存返回值, 到a中L.setField(LuaState.LUA_GLOBALSINDEX, "a");//读入aLuaObject l = L.getLuaObject("a");//打印结果.System.out.println("Result is " + l.getString());L.close();}测试2: 传递Java对象class Value {public int i;public void inc() {i++;}public int get() {return i;}public String toString() {return "Value is " + i;}}Lua脚本: (该脚本中调用两次对象的inc方法, 并调用get方法输出结果)function test1(v)v:inc();v:inc();print("In lua: " .. v:get());return vend Java 代码: (前面都一样, 略)//找到函数est1L.getField(LuaState.LUA_GLOBALSINDEX, "test1");//生成新的对象供测试Value v = new Value();//对象压栈L.pushObjectValue(v);//调用函数test1, 此时1个参数, 1个返回值L.call(1, 1);//结果放在b中.L.setField(LuaState.LUA_GLOBALSINDEX, "b");LuaObject l = L.getLuaObject("b");System.out.println("Result is " + l.getObject());
总结:运行结果:Result is Value is 2In lua: 2 和预期的一致.

如何在Java中使用Lua脚本语言是本文要介绍的内容,主要是来学习LUA脚本语言在JAVA中如何来使用,Lua就不说了, 现在比较热门, 语法也很简单. 为了在Java中调用, 折腾了比较长的时间, 就把一些东西记在下面.来看详细内容讲解。
Lua是支持内嵌在C程序中的, 但是官方不支持Java. 在网上查了下, 有LuaJava开源库, 拿来试用了一下, 发现这个库还算比较完善的.

这个LuaJava实际上就是按照Lua官方文档, 把Lua的C接口通过JNI包装成Java的库. 下载, 里面是一个.dll, 一个.jar. 把.dll放到java.library.path下, 再把.lib放到classpath中, helloworld运行OK.
但是, 测试的时候, 很快发现了第一个问题: 在调用LuaJava中提供的LuaState.pushInteger 方法的时候, 出现了错误 : Unsatisfied Link Error. 其他的LuaState.pushNumber方法倒是没有问题. 用Depends工具看了下, 这个.dll居然没有导出pushInteger这个函数. 晕....
下载LuaJava的源代码, 查看了下Luajava.c 和 Luajava.h, 发现果然里面有点问题, 在.h里面定义了JNI中对应Java函数的C函数
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger
但是.c中没有实现这个函数. 无语, 看来大马虎哪都有啊. 幸亏有源代码, 照猫画虎在Luajava.c中加上这个函数的实现,
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger (JNIEnv * env, jobject jobj, jobject cptr, jint i) { lua_State * L = getStateFromCPtr( env , cptr ); lua_pushinteger(L, i); }

然后编译. 编译也出现了问题了, 官方文档中说可以用VC++来Build, 但是没有说官方用的是什么版本. 我用VC2005就不行. 好在Luajava比较小, 就一个.h 一个 .c , 在VC中新建一个.dll项目, 把文件加进去, 修改一下build参数 (Include 需要加上lua的头文件, lib中需要加上lua的.lib文件, 另外要选上 Compile as C Code (/TC) ) Build, 通过了.
这时再在Java中调用pushInteger方法就没有问题了.
在测试中, 发现Luajava提供的文档中, 对于Lua脚本怎么调用Java对象/方法很详细, 但是在Java中怎么调用Lua函数/取得返回值 就没有. 参考了http://www.lua.org/manual/5.1/manual.html#lua_CFunction 的Lua C文档, 实现了传递对象到Lua中并取得返回值的代码:
Test1: 测试传递简单类型, 并取得返回值:
Lua 脚本(test.lua):
function test(a,b) return a+b end

Java代码:
static { //加载Lua5.1.dll, 因为LuaJava最后还是要调用Lua的东西 System.loadLibrary("lua5.1"); } public static void main(String[] argu) throws LuaException { LuaState L = LuaStateFactory.newLuaState(); L.openLibs(); //读入Lua脚本 int error = L.LdoFile("test.lua"); if (error != 0) { System.out.println("Read/Parse lua file error. Exit."); return; } //找到函数test L.getField(LuaState.LUA_GLOBALSINDEX, "test"); //参数1压栈 L.pushInteger(1); //参数2压栈 L.pushInteger(2); //调用!! 一共两个参数, 1个返回值 L.call(2, 1); //保存返回值, 到a中 L.setField(LuaState.LUA_GLOBALSINDEX, "a"); //读入a LuaObject l = L.getLuaObject("a"); //打印结果. System.out.println("Result is " + l.getString()); L.close(); }

测试2: 传递Java对象
class Value { public int i; public void inc() { i++; } public int get() { return i; } public String toString() { return "Value is " + i; } }

Lua脚本: (该脚本中调用两次对象的inc方法, 并调用get方法输出结果)
function test1(v) v:inc(); v:inc(); print("In lua: " .. v:get()); return v end

Java 代码: (前面都一样, 略)
//找到函数test1 L.getField(LuaState.LUA_GLOBALSINDEX, "test1"); //生成新的对象供测试 Value v = new Value(); //对象压栈 L.pushObjectValue(v); //调用函数test1, 此时1个参数, 1个返回值 L.call(1, 1); //结果放在b中. L.setField(LuaState.LUA_GLOBALSINDEX, "b"); LuaObject l = L.getLuaObject("b"); System.out.println("Result is " + l.getObject());

运行结果:
Result is Value is 2 In lua: 2

和预期的一致.
实现一个怪物的创建,把lua里的设定当作初始状态传给monstor,名字为sample monstor,防御10,攻击10,生命100
1.先导入lib--luajava-1.1.jar
import org.keplerproject.luajava.LuaState; import org.keplerproject.luajava.LuaStateFactory; public class Load{ LuaState luaState; /** * Constructor * @param fileName File name with Lua . */ Load(final String fileName) { this.luaState = LuaStateFactory.newLuaState(); this.luaState.openLibs(); this.luaState.LdoFile(fileName); } /** * Ends the use of Lua environment. */ void close() { this.luaState.close(); } /** * Call a Lua inside the Lua to insert * data into a Java object passed as parameter * @param Name Name of Lua . * @param obj A Java object. */ void run(String Name, Object obj) { this.luaState.getGlobal(Name); this.luaState.pushJavaObject(obj); this.luaState.call(1,0); } } public class Monster{ /* Info */ protected String race; protected int defense; protected int attack; protected int life; /* */ private Load ; public Monster(String race) { /* Loads Lua for this race.*/ this. = new Load(race+".lua"); /*Call Lua create .*/ .run("create", this); } public void setRace(String race) { this.race = race; } public String getRace() { return race; } public int getDefense() { return this.defense; } public void setDefense(int defense) { this.defense = defense; } public int getLife() { return this.life; } public void setLife(int life) { this.life = life; } public void setAttack(int attack) { this.attack = attack; } public int getAttack() { return this.attack; } } monstor.lua--- create(monster) monster:setRace("Sample Monster") monster:setDefense(10) monster:setAttack(10) monster:setLife(100) end

但总是抛出这个错误:
PANIC: unprotected error in call to Lua API (Invalid method call. No such method.)

不知为何,以后用到的时候再research.
已经查出来,原来在Monster类中少了个方法:
public void setRace(String race) { this.race = race; }

怪不得会找不到,
要在一lua文件a.lua里导入其他的lua文件b.lua,用require "b"
如果要从lua中运算后得到返回参数,则需要做一下修改:在lua文件中改成:
create(monster) monster:setRace("Sample Monster") monster:setDefense(10) monster:setAttack(10) monster:setLife(100) return monster end

在Load.java中的run改成如下:
void run(String Name, Object obj) { this.luaState.getGlobal(Name); this.luaState.pushJavaObject(obj); this.luaState.call(1, 1);// 一个参数,0个返回 try { Object object =luaState.getObjectFromUserdata(1); } catch (LuaException e) { e.printStackTrace(); } }

转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦

从 sf.net 下载 luaj

java代码,执行lua脚本!
答:要在Java上使用Lua脚本,必须有关于Lua脚本解释器以及Java程序可以访问这些脚本的相关API,即相关类库。可以使用一个叫做LuaJava的开源项目,可以在www.keplerproject.org/luajava/ 找到LuaJava的类库以及源代码,使用文档资等

请教如何用.lua调用.java包内的方法和变量
答:1.lua加入到环境变量中。即cmd可以识别lua命令 (右键计算机-》高级系统设置 在高级面板 -》环境变量 在系统变量或者用户变量中找到path(没有就新建path) path 中加入lua的路径即可,如:D:\Developments\Lua\5.1(原来有path时,在原来的path值后加分号,再加路径,如:原来的值;D:\Developments\Lua...

(游戏lua脚本控制台的使用方法)
答:接下来,我们将介绍一些常用的lua控制台指令。“godmode”,这个指令可以让玩家无敌,不会受到任何伤害。“spawn”,可以刷怪物或物品。还有“give”,可以获得任意物品。这些指令可以让玩家在游戏中更加自由地探索和体验,极大地增加了游戏的乐趣和挑战性。除了常用指令外,lua控制台还可以实现更多高级操作。

java调用lua怎么传参数
答:这个最好用jni+ lua/c api才可以。或者用别人在jvm里面实现的lua虚拟机

在java中调用lua执很多次之后,内存使用率持续上升,无法释放
答:要看LuaState luaState = LuaStateFactory.newLuaState();和 luaState.close();的实现方式。lua中有调用内存分配用户对象,但没注册gc的话,luastate的close不会释放内存。

基于Redis + Lua脚本的设计红包雨
答:首先,运营系统通过配置Redis存储红包信息,用户只需轻轻一点,TCP网关便会调用答题服务,执行预编写的Lua脚本。这个脚本如同红包发放的指挥棒,异步地将奖品存入用户的账户,确保了原子性和隔离性。Redis事务的稳健防护 在Redis事务中,错误处理至关重要。如果遇到非存在的命令,事务会自动回滚,保证数据的...

gta午夜lua脚本怎么用
答:1、启动午夜lua脚本。2、打开gta游戏。3、在游戏的主界面按下“HOME”键即可呼出功能菜单。4、进入到游戏中,勾选功能菜单中的选项,即可使用各种功能。

如何在java程序中调用linux命令或者shell脚本
答:java程序是提供了这个一方法, Process pro = Runtime.getRuntime().exec(cmds); 但是一般来说,尽量去用一些其他脚本(lua,shell,python)去执行一系列linux命令比较灵活, 而且耗费资源少。但是Runtime.getRuntime().exec()这种调用方式在java虚拟机中是十分消耗资源的,即使命令可以很快的执行完毕...

请问自己的软件如何运行Lua脚本
答:用户可以编写lua脚本来完成一些特定功能的机器人。你要做的就是使用lua c api来在你的程序中执行lua。类似这种:int iErr = 0;lua_State *lua = lua_open (); // Open Lua luaopen_io (lua); // Load io library if ((iErr = luaL_loadfile (lua, "test.lua")) == 0){ //...

lua文件怎么打开怎么使用
答:tar zxf lua-5.3.0.tar.gz cd lua-5.3.0 make linux test make install 接下来我们创建一个 HelloWorld.lua 文件,代码如下:print("Hello World!")执行以下命令运行:lua HelloWorld.lua (2)windows下安装和使用 在windows下安装 Lua可以使用一个叫"SciTE"的IDE环境来执行lua程序,下载地址为:...

IT评价网,数码产品家用电器电子设备等点评来自于网友使用感受交流,不对其内容作任何保证

联系反馈
Copyright© IT评价网