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/

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

  1. Java调用Lua脚本(LuaJava使用、安装及Linux安装编译)

    依赖包(附件有下载): 包名 类型 操作系统 luajava-1.1.jar jar ALL libluajava-1.1.so .so linux luajava-1.1.dll .dll wind ...

  2. Java调用Lua脚本(热载实现)

    前言: Lua作为解析执行的脚本语言, 往往是易变逻辑编写的首选语言, 尤其是在游戏领域. C/C++和Lua的结合, 往往了标配. 比如Redis, Nginx其对Lua的支持, 也是杠杠的. 当然 ...

  3. lua调用java java调用lua[转载]

    转载:http://dualface.github.io/blog/2013/01/01/call-java-from-lua/LuaJavaBridge - Lua 与 Java 互操作的简单解决方 ...

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

    通过c++调用lua 脚本,    环境VC++6.0    lua  sdk 5.1.4 在调用前先认识几个函数.1.调用lua_open()将创建一个指向Lua解释器的指针.2. luaL_ope ...

  5. 使用redis调用lua脚本的方式对接口进行限流

    java端实现: //初始化一个redis可执行的lua DefaultRedisScript<List> defaultRedisScript = new DefaultRedisScr ...

  6. c++调用lua

    我们主要解决如下几个问题: 转:http://www.cnblogs.com/zisou/p/cocos2dx-lua2.html http://www.cnblogs.com/sevenyuan/p ...

  7. JAVA调用 keytool 生成keystore 和 cer 证书

    keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据: 密钥实体( ...

  8. java调用mysql服务做备份与恢复

    首先添加mysql的bin到环境变量,这样可以简写部分命令,并且做到不依赖系统mysql的具体安装路径. 重启计算机可以让添加的环境变量在java代码中调用时生效.(cmd中生效但java中调用没有生 ...

  9. 存储过程详解与java调用(转)

    存储过程的一些基本语法: --------------创建存储过程----------------- CREATE PROC [ EDURE ] procedure_name [ ; number ] ...

随机推荐

  1. haproxy 服务端超时时间 timeout server 17000 --后台程序17秒没有响应,返回超时

    haproxy 服务端超时时间: haproxy 配置: timeout server 17000 --后台程序17秒没有响应,返回超时 Jun 27 09:29:56 localhost hapro ...

  2. EXTJS4两个ComboBox的数据源联动,解决遇到第二个ComboBox第二次以后显示忙的状态问题

    定义如下[红色部分是后加上的,它是解决问题的关键]: var bu_store = Ext.create('Ext.data.Store', { fields: ['key', 'value'], r ...

  3. [Android学习笔记]ListView中含有Button导致无法响应onItemClick回调的解决办法

    转自:http://www.cnblogs.com/eyu8874521/archive/2012/10/17/2727882.html 问题描述: 当ListView的Item中的控件只是一些展示类 ...

  4. 8张图理解Java(转)

    一图胜千言,下面图解均来自Program Creek 网站的Java教程,目前它们拥有最多的票选.如果图解没有阐明问题,那么你可以借助它的标题来一窥究竟. 1.字符串不变性 下面这张图展示了这段代码做 ...

  5. <Win32_17>集音频和视频播放功能于一身的简易播放器

    前段时间,在学习中科院杨老师的教学视频时,他说了一句话: "我很反对百八十行的教学程序,要来就来一个完整的程序" 对此,我很是赞同.所谓真刀真枪的做了,你才会发现其中的奥秘——然而 ...

  6. Codeforces Round #296 (Div. 2) A. Playing with Paper

    A. Playing with Paper One day Vasya was sitting on a not so interesting Maths lesson and making an o ...

  7. 【Cocos2d-X开发学习笔记】第30期:游戏中数据的存储(下)

    本系列学习教程使用的是cocos2d-x-2.1.4(最新版为3.0alpha0-pre) ,PC开发环境Windows7,C++开发环境VS2010 一.对数据进行编解码 在上一期中,我们使用了CC ...

  8. fusionchart实现ZoomLine 源码 破解版 能够导出

    近期画油量曲线须要用到ZoomLine官网看了好几天.如今整理出来供大家參考使用 zoomline.html源码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD ...

  9. Android拖动和缩放图片

    Android拖动和缩放图片 2014年5月9日 我们在使用应用其中常常须要浏览图片.比方在微信其中.点击图片之后能够对图片进行缩放. 本博客介绍怎样对图片进行拖拽和缩放.这首先要了解Android中 ...

  10. VMware Player安装centos

    用VMware Player安装centos 到物理硬盘 想要學Linux,但卻不知道如何弄成雙系統?那就使用用虛擬機器來安裝Linux.使用虛體機器來玩,好處除了好裝之外,也不怕把電腦搞壞,不論你怎 ...