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-11-01 02:33:30

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

线程-java调用sqlplus下载数据库文件到本地后,如果用java关闭此进程,大神戳进来

问题描述 java调用sqlplus下载数据库文件到本地后,如果用java关闭此进程,大神戳进来 1.用java调用sqlplus,将指定的存储过程下载到本地作为文本文件2.在java读取此本地文件做处理,处理后写1个新的文本文件在本地我将上面2个步骤用2个进程thread1,thread2因为步骤2必须等步骤1结束才能执行,所以我调用thread1.start()thread1.join()以及thread2.start().但是运行结果是每次都只执行出了步骤1,步骤2执行不出来.考虑是否在步

java调用swt.jar包dll文件的加载问题?

问题描述 java调用swt.jar包dll文件的加载问题? 调用swt.jar时,报错 Exception in thread "AWT-EventQueue-2" java.lang.UnsatisfiedLinkError: no swt-win32-3347 or swt-win32 in swt.library.path, java.library.path or the jar file at org.eclipse.swt.internal.Library.loadLib

Java 调用底层接口的几种方法

Java 调用底层接口 Java 调用底层接口要通过动态链接库进行,在windows下是dll文件,linux是so文件 Java调用动态库所需要关心的问题:     如何装载文件,以及如何定位所要使用的方法:      数据类型是如何对应的:     如何给使用的方法传递参数:     如何获取返回的值. 目前调用底层接口用的比较多的技术包括jni.jna.jnative.Nativecall等 JNI 封装本地接口 JAVA可以通过JNI接口访问本地的动态连接库,从而扩展JAVA的功能.使用

java 调用wsdl接口 大神帮忙讲解一下

问题描述 java 调用wsdl接口 大神帮忙讲解一下 现有一接口是c++写的 java调用他如何调用这个接口?在浏览器上显示为 解决方案 参考下:http://yang-min.iteye.com/blog/600172

java调用matlab程序

在实际Java编程中,我们可能想要使用matlab编写一些复杂的数值计算算法,然后导入我们的java项目中调用.这首先需要我们matlab的jdk版本和java项目的jdk版本对应一致.想查看matlabjdk版本,可以在matlab命令行中输入version -java来查看,会看到类似下面的内容: Java 1.7.0_60-b19 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode .下面我们来看看mat

C# 制作Com组件:java调用.net DLL的方法

本文将详细为大家介绍一个java调用.net DLL的方法,以实现特殊的客户的特殊要求:"在Java项目中必须使用其提供的用.net写的DLL加密机制!" 环境与工具: ◆.net framework 3.5 C# ◆java jdk1.5, Tomcat 5.5 ◆jacob-1.15-M3 实现例子: 一.C# 制作Com组件 新建一个Class 项目,取名TestCom 代码 using System;  using System.Collections.Generic;  us

JAVA调用动态链接库DLL:JNative学习

JAVA调用动态链接库DLL的方法有:JNI(Java Native Interface),JInvoke,JNative(Java to native interface),JNI是JAVA自身提供的方法:JInvoke从何而来不得而知,好像还需要注册付费的,64位的JDK.JIR环境下运行不了,在VMware下安装的WindowsXP下同样有问题:JNative是开源的,但相关资料文档也特别的少,好像已经停止更新了.JNative源码地址:http://jnative.cvs.sourcef

如何使用java调用python下载网页

本篇参考:http://tonl.iteye.com/blog/1918245 python版本:2.7 64bit window版本: 下载python:http://www.python.org/getit/ Python 2.7.5 Windows X86-64 Installer (Windows AMD64 / Intel 64 / X86-64 binary [1] -- does not include source),进行安装: 首先编写下面的spider.py脚本: # -*-

Java调用命令实现视频上传过程中自动转换为flv格式并截图生成缩略图

//视频上传过程中自动转换为flv格式并截图生成缩略图(Java调用命令实现) import java.util.ArrayList; import java.util.List; public class VideoProcess { System.out.println(oldfilepath+"->"+newfilename+"- >"+newimg); List<String> commendF = new ArrayList<