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

package app;

import org.luaj.vm2.LuaValue;

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

public class Calc {

public static void main(String[] args) {

long key = getKey();

System.out.println(key);

System.out.println(getKeyJava());

}

public static long getKey() {

//获取一个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();

return key.checklong();

}

//用java实现的,比较用

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

public static long getKeyJava() {

long tm = 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

package lualib;

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等

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

public class Math extends OneArgFunction {

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

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

public LuaValue call(LuaValue modname) {

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

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

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

LuaValue lib = tableOf();

//设置timestamp方法

lib.set("timestamp", new lua_timestamp());

//设置异或方法

lib.set("bitxor", new lua_bitxor());

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

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

return lib;

}

static class lua_timestamp extends ZeroArgFunction {

public LuaValue call() {

return LuaValue.valueOf(System.currentTimeMillis() / 1000);

}

}

static class lua_bitxor extends TwoArgFunction {

public LuaValue call(LuaValue a, LuaValue b) {

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

long pa = a.checklong();

long pb = b.checklong();

long r = pa ^ pb;

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

return LuaValue.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")

-- 模板方法

function genkey()

tm = jlib.timestamp()

a = div.div(tm, 1000)

b = div.div(tm, 400)

r = jlib.bitxor(a, b)

return r

end

div.lua

1

2

3

4

5

6

module(..., package.seeall)

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

function div(a, b)

return math.floor(a / b)

end

3.总结

总体上来说调用起来还算容易,只是文档有些缺乏。
如果要用Lua5.2则必须用LuaJ3.0。LuaJ3.0和2.0.3还是有一些不一样的,可以参考前文提到的详细介绍。

http://levelup.sinaapp.com/

时间: 2024-12-15 05:00:14

Java调用Lua(转)的相关文章

VC和VS调用Lua设置以及Lua C API使用。

通过c++调用lua 脚本,    环境VC++6.0    lua  sdk 5.1.4 在调用前先认识几个函数.1.调用lua_open()将创建一个指向Lua解释器的指针.2. luaL_openlibs()函数加载Lua库.3.使用luaL_dofile()加载脚本并运行脚本.4. lua_close()来关闭Lua指向解释器的指针. 5.调用lua_getglobal()将add()函数压入栈顶,add()为lua函数.6.第一个参数x,通过调用lua_pushnumber()入栈.7

Java调用WebService 接口 实例

这里给大家介绍一下,Java调用webservice的一个实例的过程. 本项目不能运行,因为接口地址不可用. 这里只是给大家介绍一个过程,同时留作自己的笔记.如果要学习,可以参照别人的实例.比较好. ①选择项目根目录的src ,右键,new --> webservice client 然后输入地址: http://172.18.100.52:456/hello?wsdl 必须要加wsdl结尾,这样才是一个webservice的接口. finlish.这时候刷新项目.可以看到项目下/src/com

java 调用 keytool 生成keystore 和 cer 证书

keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据: 密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密) 可信任的证书实体(trusted certificate entries)——只包含公钥 ailas(别名)每个keystore都关联这一个独一无二的alias,这个alias通常不区分大小写 下面给出一

java调用phantomjs采集ajax加载生成的网页

java调用phantomjs采集ajax加载生成的网页 日前有采集需求,当我把所有的对应页面的链接都拿到手,准备开始根据链接去采集(写爬虫爬取)对应的终端页的时候,发觉用程序获取到的数据根本没有对应的内容,可是我的浏览器看到的内容明明是有的,于是浏览器查看源代码也发觉没有,此时想起该网页应该是ajax加载的.不知道ajax的小朋友可以去学下web开发啦. 采集ajax生成的内容手段不外乎两种.一种是通过http观察加载页面时候的请求,然后我们模仿该请求去得到对应的内容,第二种则是模仿浏览器行为

简述C/C++调用lua中实现的自定义函数

1.首先说下目的,为什么要这么做 ? 正式项目中,希望主程序尽量不做修改,于是使用C/C++完成功能的主干(即不需要经常变动的部分)用lua这类轻量级的解释性语言实现一些存在不确定性的功能逻辑:所以,程序功能如有问题,只需对lua脚本作出修改,而修改脚本的好处是简单高效,改完脚本后重新执行程序便能看到效果.  2.具体怎么做? 一般来说,C/C++调用lua接口或是数据交互,首先要做的是包含lua相关操作的头文件以及lua库相关的头文件,然后调用接口创建lua环境.用操作栈的规则和lua交互数据

Java调用Linux命令(cd的处理)

一.Java调用Linux系统的命令非常简单 这是一个非常常用的调用方法示例: 1 public String executeLinuxCmd(String cmd) { 2 System.out.println("got cmd job : " + cmd); 3 Runtime run = Runtime.getRuntime(); 4 try { 5 Process process = run.exec(cmd); 6 InputStream in = process.getIn

JAVA调用Shell脚本

在实际项目中,Java有时候需要调用C写出来的东西,除了JNI以外,我认为一种比较好的方法是JAVA调用Shell.先把C写出来的make成可执行文件,然后再写一个shell脚本执行该可执行文件,最后是JAVA调用该shell脚本. JAVA调用很简单,例子如下: 首先是shell脚本 [plain] view plain copy print? #!/bin/sh echo Begin word cluster /home/felven/word2vec/word2vec -train /ho

ndk学习17: jni之Java调用C&C++

一.Hello World 1. 定义函数原型 native关键字定义的函数即为jni函数 2.生成头文件 切换到src目录执行: (这个过程可以写脚本自动完成,比如自动拷贝到jni目录) javah -jni 包名.类名 在根目录下生成: org_bing_testjni_MainActivity.h 3. 工程中添加jni代码 工程右键->添加native code->输入名字->finish 多了如下文 新建一个Application.mk,配置相关选项(详细查看ndk有关Appl

C++调用Lua的性能测试

游戏服务器经典的架构就是C++和Lua的结合,C++开发主体框架,Lua实现一些复杂的逻辑.我们都知道Lua是一种非常快的语言,但是到底有多块,我们测试下看看. C++调用Lua的性能测试,发现不对的地方望提出. 实验一:我们使用C++调用Lua带8个以上参数的函数,而这个函数里面什么也没有做.我们通过这个实验能够简单地测试出:使用Lua虚拟机和向调用栈当中传入8+个参数和Lua取出这些参数的时间.但是其中的参数类型比较多样,有整形,浮点型,和数组.实验的Lua函数比较简单,如下: functi