当前位置: 首页 > news >正文

在Java中使用Lua脚本语言

Lua是支持内嵌在C程序中的, 但是官方不支持Java. 在网上查了下, 有LuaJava开源库, 拿来试用了一下, 发现这个库还算比较完善的. 地址是
http://www.keplerproject.org/luajava/  
这个LuaJava实际上就是按照Lua官方文档, 把Lua的C接口通过JNI包装成Java的库. 下载, 里面是一个.dll, 一个.jar. 把.dll放到 java.library.path  下, 再把.lib放到 classpath  中, helloworld运行OK.
但是, 测试的时候, 很快发现了第一个问题: 在调用LuaJava中提供的 LuaState.pushInteger  方法的时候, 出现了错误 :  Unsatisfied Link Error  . 其他的 LuaState.pushNumber  方法倒是没有问题. 用Depends工具看了下, 这个.dll居然没有导出 pushInteger  这个函数。
下载LuaJava的源代码, 查看了下Luajava.c 和 Luajava.h, 发现果然里面有点问题, 在.h里面定义了JNI中对应Java函数的C函数
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger 
但是.c中没有实现这个函数. 无语, 看来大马虎哪都有啊. 幸亏有源代码, 照猫画虎在Luajava.c中加上这个函数的实现,
JNIEXPORT void JNICALL Java_org_keplerproject_luajava_LuaState__1pushInteger
   (JNIEnv * env, jobject jobj, jobject cptr, jint i)
{
    lua_State * L = getStateFromCPtr( env , cptr );
    lua_pushinteger(L, i);
}
 

然后编译. 编译也出现了问题了, 官方文档中说可以用VC++来Build, 但是没有说官方用的是什么版本. 我用VC2005就不行. 好在Luajava比较小, 就一个.h 一个 .c , 在VC中新建一个.dll项目, 把文件加进去, 修改一下build参数 (Include 需要加上lua的头文件, lib中需要加上lua的.lib文件, 另外要选上  Compile as C Code (/TC)  ) Build, 通过了.
这时再在Java中调用pushInteger方法就没有问题了.
在测试中, 发现Luajava提供的文档中, 对于Lua脚本怎么调用Java对象/方法很详细, 但是在Java中怎么调用Lua函数/取得返回值 就没有. 参考了 http://www.lua.org/manual/5.1/manual.html#lua_CFunction  的Lua C文档, 实现了传递对象到Lua中并取得返回值的代码:
Test1: 测试传递简单类型, 并取得返回值:
Lua 脚本(test.lua):
function test(a,b)
    return a+b
end
 
Java代码:
static {
        //加载Lua5.1.dll, 因为LuaJava最后还是要调用Lua的东西
        System.loadLibrary("lua5.1");
    }
         public static void main(String[] argu) throws LuaException {
         LuaState L = LuaStateFactory.newLuaState();
        L.openLibs();
        //读入Lua脚本
        int error = L.LdoFile("test.lua");
        if (error != 0) {
            System.out.println("Read/Parse lua file error. Exit.");
            return;
        } 
          //找到函数test
        L.getField(LuaState.LUA_GLOBALSINDEX, "test");
        //参数1压栈
        L.pushInteger(1);
        //参数2压栈
        L.pushInteger(2);
        //调用!! 一共两个参数, 1个返回值
        L.call(2, 1);
        //保存返回值, 到a中
        L.setField(LuaState.LUA_GLOBALSINDEX, "a");
        //读入a
        LuaObject l = L.getLuaObject("a");
        //打印结果.
        System.out.println("Result is " + l.getString());
        L.close();
}

测试2: 传递Java对象
class Value {
    public int i;
    public void inc() {
        i++;
    }
    public int get() {
        return i;
    }
    public String toString() {
        return "Value is " + i;
    }
}
Lua脚本: (该脚本中调用两次对象的inc方法, 并调用get方法输出结果)
function test1(v)
    v:inc();
    v:inc();
    print("In lua: " .. v:get());
    return v
end
 
Java 代码: (前面都一样, 略)
        //找到函数est1
        L.getField(LuaState.LUA_GLOBALSINDEX, "test1");
        //生成新的对象供测试
        Value v = new Value();
        //对象压栈
        L.pushObjectValue(v);
        //调用函数test1, 此时1个参数, 1个返回值
        L.call(1, 1);
        //结果放在b中.
        L.setField(LuaState.LUA_GLOBALSINDEX, "b");
        LuaObject l = L.getLuaObject("b");
        System.out.println("Result is " + l.getObject());
运行结果:
Result is Value is 2
In lua: 2
 
和预期的一致.

转载于:https://www.cnblogs.com/blogyuan/archive/2013/05/22/3739665.html

相关文章:

  • python正则
  • [HEOI2013]ALO
  • 20172304 2017-2018-2 《程序设计与数据结构》第七周学习总结
  • 【语言处理与Python】4.2序列
  • 关于iOS网络访问权限的问题
  • Repository设计模式
  • Launcher中Shortcut的创建流程简析
  • thymeltesys-基于Spring Boot Oauth2的扫码登录框架
  • windows下揪出java程序占用cpu很高的线程 并找到问题代码 死循环线程代码
  • 如何格式化日期和时间
  • [R] data.frame() creates list?
  • 任意选若干个不相邻的数得到的和最大【dp】
  • C++ sort使用两个参数来排序
  • SmallSlider 图片轮播插件
  • 旅游网站CheapAir.com以BCH作为比特币支付
  • [PHP内核探索]PHP中的哈希表
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • Angular2开发踩坑系列-生产环境编译
  • Angular数据绑定机制
  • docker容器内的网络抓包
  • hadoop集群管理系统搭建规划说明
  • javascript数组去重/查找/插入/删除
  • JS函数式编程 数组部分风格 ES6版
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • LeetCode29.两数相除 JavaScript
  • Mac转Windows的拯救指南
  • nfs客户端进程变D,延伸linux的lock
  • python 装饰器(一)
  • spring cloud gateway 源码解析(4)跨域问题处理
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 从tcpdump抓包看TCP/IP协议
  • 大整数乘法-表格法
  • 第2章 网络文档
  • 二维平面内的碰撞检测【一】
  • 好的网址,关于.net 4.0 ,vs 2010
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 看域名解析域名安全对SEO的影响
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 前端js -- this指向总结。
  • 协程
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • elasticsearch-head插件安装
  • FaaS 的简单实践
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #100天计划# 2013年9月29日
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (pojstep1.3.1)1017(构造法模拟)
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)springboot猪场管理系统 毕业设计 160901
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (算法)求1到1亿间的质数或素数
  • (太强大了) - Linux 性能监控、测试、优化工具