java转lua_Java调用Lua(转)

Java 调用 Lua

app发版成本高,覆盖速度慢,覆盖率页低。一些策略上的东西如果能够从服务端控制会方便一些。

所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言。

总体上看是一个模板方法模式。Lua提供模板方法,其中需要的一些具体实现则有宿主语言Java提供。

1. Luaj:Java与Lua的桥梁

能够作为Java与Lua进行通信的桥梁工具还有别的一些。

但是Luaj 是用纯Java实现,客户端容易加载。且目前还一直有更新和维护,相对感觉靠谱。

需要注意的是: 新版的LuaJ3.0是针对Lua5.2开发的,对Lua5.1会有不兼容的部分(例如module函数不能用了)

如果使用Lua5.1,则可以使用LuaJ2.0.3

2. 使用

2.1 java工程引用jse的jar包

这个简单,下载LuaJ2.0.3版,解压,加载lib/luaj-jse-2.0.3.jar

lib/里边还有个jme,这个是针对j2me环境的。

2.2 示例介绍

功能

实现一个生成时间相关的参数的功能

value = (int)(timestamp / 1000 ) ^ (int)(timestamp / 400)

^ 符号表示按位异或。

其中:

– 整个式子的计算流程由lua提供模板方法

– 除法后取整的功能由lua以module方式提供

– lua没有原生的位操作,所以这部分由java提供

– lua原生的os.time()依赖系统,于是timestamp方法由java提供,生成秒级时间戳

文件目录说明

1

2

3

4

5

6

7

8

9

10

11

.

|--lua

||--gen.lua主流程文件

|`--tool

|`--div.lua提供除法

`--src

|--app

|`--Calc.java  java的入口程序

`--lualib

`--Math.java  java提供的异或方法,和时间戳方法

2.3 具体实现

接下来就看4个文件的具体代码吧。请着重注意注释,要说的都在里边了

Calc.java:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

packageapp;

import org.luaj.vm2.LuaValue;

import org.luaj.vm2.lib.jse.JsePlatform;

publicclassCalc{

publicstaticvoidmain(String[]args){

longkey=getKey();

System.out.println(key);

System.out.println(getKeyJava());

}

publicstaticlonggetKey(){

//获取一个lua的运行环境,lua虚拟机应该就在这里了

//lua是个弱类型语言,在java里,所有从lua获得的,或者要传递给lua的,都是LuaValue对象

LuaValue _G=JsePlatform.standardGlobals();

//执行gen.lua脚本

//_G.get("dofile")获取dofile方法的对象

//get其实是获取table值的方法,dofile就是全局table的一个值

//对于Function类型的对象可以用call方法去调用,参数就是lua方法需要的参数,但是一定要转换成LuaValue类型

_G.get("dofile").call(LuaValue.valueOf("lua/gen.lua"));

//上一句执行完以后,gen.lua中的genkey函数就在全局变量中了,

//可以这样直接调用

LuaValue key=_G.get("genkey").call();

returnkey.checklong();

}

//用java实现的,比较用

//value = (int)(timestamp / 1000 ) ^ (int)(timestamp / 400)

publicstaticlonggetKeyJava(){

longtm=System.currentTimeMillis()/1000;

return(tm/1000)^(tm/400);

}

}

Math.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

packagelualib;

import org.luaj.vm2.LuaValue;

import org.luaj.vm2.lib.OneArgFunction;

import org.luaj.vm2.lib.TwoArgFunction;

import org.luaj.vm2.lib.ZeroArgFunction;

//luaj提供了一些方法模板 ZeroArgFunction OneArgFunction等

//具体可以看那个详细介绍

publicclassMathextendsOneArgFunction{

//lua的方法都是闭包,在java中一定是用类对象与之对应的。

//于是call这个方法就是调用闭包使用所调用的方法,必须实现

publicLuaValue call(LuaValue modname){

//这是类在lua里是一个模块,也就是个函数包,在lua里也就是一个table

//table的每一个元素是一个函数(闭包而已)

//这个lib就是一个table,用来存放各个lua模块方法

LuaValue lib=tableOf();

//设置timestamp方法

lib.set("timestamp",newlua_timestamp());

//设置异或方法

lib.set("bitxor",newlua_bitxor());

//这里不确定:env是该类的环境参数,暂时没研究这一句的作用,本例中不设置也没关系

//env.set(modname.checkjstring(), lib);

returnlib;

}

staticclasslua_timestampextendsZeroArgFunction{

publicLuaValue call(){

returnLuaValue.valueOf(System.currentTimeMillis()/1000);

}

}

staticclasslua_bitxorextendsTwoArgFunction{

publicLuaValue call(LuaValuea,LuaValueb){

//lua传进来参数都是LuaValue的,java使用的时候需要使用相应的check方法转为本地变量

longpa=a.checklong();

longpb=b.checklong();

longr=pa^pb;

//返回的时候需要用valueOf方法转为LuaValue类型

returnLuaValue.valueOf(r);

}

}

}

lua程序就简单多了

gen.lua

1

2

3

4

5

6

7

8

9

10

11

12

13

--注意查找目录是从工程的根目录开始的

div=require("lua.tool.div")

--引用java提供的方法,则直接写java的类名就好

jlib=require("lualib.Math")

--模板方法

functiongenkey()

tm=jlib.timestamp()

a=div.div(tm,1000)

b=div.div(tm,400)

r=jlib.bitxor(a,b)

returnr

end

div.lua

1

2

3

4

5

6

module(...,package.seeall)

--这里也可以require java提供的模块,本例没用到

functiondiv(a,b)

returnmath.floor(a/b)

end

3.总结

总体上来说调用起来还算容易,只是文档有些缺乏。

如果要用Lua5.2则必须用LuaJ3.0。LuaJ3.0和2.0.3还是有一些不一样的,可以参考前文提到的详细介绍。

http://levelup.sinaapp.com/

你可能感兴趣的:(java转lua)