详解在JAVA(J2ME)中使用Lua脚本引擎kahlua

移动开发 iOS
在JAVA(J2ME)中使用Lua脚本引擎kahlua是本文要介绍的内容,主要是来学习JAVS中如何来使用LUA,具体内容来看本文详解。

JAVA(J2ME)中使用Lua脚本引擎kahlua是本文要介绍的内容,主要是来学习JAVS中如何来使用LUALua有幸被暴雪选中,在魔兽中大量应用,从而获得了极快的发展,Lua也因此成为游戏、软件开发中脚本语言的首选。Lua是一种十分简洁的脚本语言,不过写起来并不是很简单,当然过分的简化使得程序本身有些混乱。具体的语言教程在网上有很多,这里就不再说了。

kahlua最初是为J2ME设计的,现在已经扩展到J2SE,项目地址是http://code.google.com/p/kahlua/,在这里可以下载到源代码及编译好的jar包。在实际应用中我发现J2ME中导入jar包很困难,弄了好几天也没有成功,只好将源代码放在在工程的目录里一同编译。kahlua可以识别*.lua及*.lbc文件,*.lbc是编译后的lua文件,项目中一般使用这种文件,因为不会泄露lua文件的内容。可以到http://www.lua.org上下载一个lua的运行环境,安装后会自动添加安装路径到系统变量,此时在cmd中运行luac程序就可以编译脚本,命令是luac -o f.lbc d:\f.lua,详情看帮助文档。

我下的kahlua是kahlua-release-20090611.zip源代码包,解压后是一个Ant工程,将src目录下的内容及resource中的stdlib.lua(lbc)文件复制到J2ME项目中src下。在编程之前首先说明一点,在程序中指定文件的路径时要注意对应工程文件的位置。我的工程的src文件夹对应程序中的根目录,比如说上的/src/stdlib.lua在程序中就是/stdlib.lua。

lua脚本语言中一个独特的数据类型就是表,表其实就是java中的map、哈希表,比如说下面一个表:

  1. T1 = {} -- 定义一个空表  
  2. T1[1]=10 --定义表的内容  
  3. T1["John"]={Age=27Gender="Male"

而每一个脚本文件实际上就是一个大表,每一个变量、方法都是表的成员,因此脚本的变量默认都是全局的,而且也可以定以方法为变量,kahlua正是依据这个概念来的。

1、初始化:

  1. LuaState state=new LuaState(System.out);  
  2. UserdataArray.register(state);  
  3. OsLib.register(state);  
  4. LuaCompiler.register(state); 

se.krka.kahlua.vm.LuaState对象是kahlua引擎的核心,一切操作都由它来完成,在生成LuaState对象后再进行一些注册。

2、获取全局表:

  1. LuaTable table=state.getEnvironment();  
  2.  
  3. LuaTable有一系列函数添加、获取脚本内容,最常用的有:  
  4. void rawset(Object key, Object value);//添加内容  
  5. Object rawget(Object key);//获取内容 

3、加载脚本:

  1. InputStream is=this.getClass().getResourceAsStream(scriptName);  
  2. //scriptName为脚本文件的路径  
  3. LuaClosure closure=LuaCompiler.loadis(is , "lua" , table);  
  4. //LoadCompiler为编译器,loadis为加载输入流的方法  
  5. //is为输入流;"lua"为编译器的名字,好像任意字符串都可以;table为全局表  
  6. //LuaClosure为脚本编译后的语句。 

整个脚本编译后相当于一个大的方法,并将其添加到全局表。

4、执行脚本:

  1. sate.call(closure, null);  
  2. LuaState的public Object call(Object fun, Object[] args) 

方法是用来执行全局表中的方法,前面说到,整个脚本编译后是作为一个方法存入全局表的,因此也可以用这个方法执行脚本。

5、方法:

public Object call(Object fun, Object[] args)中fun为函数对象,args为参数

(1)在Java中调用Lua方法

  1. state.call( table.rawget("say") , new String[]{"Hello!"}); 

即从全局表中取出函数并执行。

(2)在Lua中调用Java方法

首先生成一个继承自JavaFunction接口的类,然后添加到全局表中

JavaFunction只有一个public abstract int call(LuaCallFrame callFrame, int nArguments)方法,其中callFrame用于获取输入参数及指定返回值,nArguments获取输入参数数量。返回值为返回参数的个数,因为lua函数可以有多个返回值的。

  1. class JavaFunctionSay implements JavaFunction{  
  2. public int call(LuaCallFrame frame, int arg) {  
  3. String str=BaseLib.rawTostring(frame.get(0));//获取输入参数  
  4. say(str);//执行对应Java内容  
  5. frame.push("result");//返回参数  
  6. return 1;  
  7. }   

再用table.rawset("say", new JavaFunctionSay());添加到全局表,这样就可以在对应Lua脚本中使用say方法了。

附注:

kahlua显示中文有问题,应该是编码不正确,修改LexState中String newstring( byte[] chars, int offset, int len )方法的第一行编码为"GBK"后好像就可以了。
本人在windows中使用用luac生成的lbc时出错..文件不支持中文,有中文就会报错,而英文就能顺利通过,想来可能和字符编码有关系...想在lbc中使用中文,本人的方法是:

  1. File luascript = new File("E:\\getWeather.lua");//--其实什么后缀名无所谓的  
  2. File lbcscript=new File("C:\\Users\\信丰boy\\getWeather.lbc");  
  3. closure = LuaCompiler.loadis(new FileInputStream(luascript), "信丰boy",table);//"信丰boy"这个字符串是可以随意的.其作用是表示作用域.  
  4. OutputStream os=new FileOutputStream(lbcscript);  
  5. closure.prototype.dump(os);//这样就把lbc格式的字节码文件写到"C:\\Users\\信丰boy\\getWeather.lbc"了.  
  6. os.close(); 

当下次要调用的时候

  1. File lbcscript=new File("C:\\Users\\信丰boy\\getWeather.lbc");  
  2. closure = LuaPrototype.loadByteCode(new FileInputStream(lbcscript), table); 

ps:kuhlua不支持gfind函数,所有你得用find函数ps:kuhlua不支持gfind函数,所有你得用find函数。

小结:详解在JAVA(J2ME)中使用Lua脚本引擎kahlua的内容介绍完了,希望通过本文的学习能对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-09-01 16:45:15

J2MELua

2010-09-30 11:16:53

J2ME Snake脚

2010-10-09 15:00:22

SnakeJ2ME

2010-09-29 08:57:04

J2ME前景

2009-06-17 11:27:00

setClip方法J2ME

2010-09-30 13:48:10

J2ME游戏引擎

2010-09-29 13:23:12

J2MEPIM

2010-09-29 10:41:18

J2MEJVM

2010-09-29 16:20:06

J2MEWeb服务API

2010-09-30 09:56:26

J2ME Polish

2009-07-09 16:06:10

JDK J2EE J2

2009-06-16 16:03:12

缓存J2ME

2010-09-30 12:53:00

J2MECSS

2010-09-30 11:04:53

J2MERMS

2010-09-29 09:19:39

J2ME开发工具

2010-09-30 13:39:52

2010-10-09 15:58:36

J2ME图形

2009-03-22 09:38:03

Android移植J2ME

2009-06-23 11:30:16

RMSJ2ME

2010-09-30 13:28:55

J2ME图形
点赞
收藏

51CTO技术栈公众号