`
yangzb
  • 浏览: 3500578 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在Java中使用Lua脚本语言

    博客分类:
  • Java
阅读更多

Lua就不说了, 现在比较热门, 语法也很简单. 为了在Java中调用, 折腾了比较长的时间, 就把一些东西记在下面.

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 代码: (前面都一样, 略)

        //找到函数test1
        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


和预期的一致.

分享到:
评论
7 楼 屌丝的未来在哪里 2014-08-13  
尝试将一个java中的List对象传递给Lua进行操作,发现性能不行啊,一个size为300的list,遍历一遍并进行三两行简单的操作,要60多毫秒,同样的操作如果用java代码不到1ms,请问遇到过类似问题吗,瓶颈是在什么地方呢?
6 楼 yellfly 2012-07-20  
wxw3130056tom.com 写道
我下载的源码中没有 luajava.h 文件:麻烦兄弟给发一份:
我的邮箱:wangxinwei@into4g.com


博主用的可能是不同的源代码版本,我发现从LuaForge上和github上下的源代码大小是不一样的,虽然都是1.1。
我下的版本也没有luajava.h,但实际上这个文件没有什么用,因为不需要在其它C语言源代码中包含。但因缺少jni.h编译会报错,修正办法是将#include "luajava.h" 改成 #include <jni.h>。
5 楼 wxw3130056tom.com 2011-10-21  
我下载的源码中没有 luajava.h 文件:麻烦兄弟给发一份:
我的邮箱:wangxinwei@into4g.com
4 楼 guobosheng 2010-06-23  
关于重新编译的问题:我下载的LuaJava的源代码没有头文件 Luajava.h
楼主能否给我发一个Luajava.h文件,或者编译好的dll文件?谢谢!287352794g@qq.com
3 楼 guobosheng 2010-06-23  
关于重新编译的问题:我下载的LuaJava的源代码没有头文件 Luajava.h
2 楼 guobosheng 2010-06-23  
上面的问题通过修改PATH变量来达到设置java.library.path属性的目的(改变之后Eclipse需要重新启动)
参考:http://dongjiliwu.iteye.com/blog/421726
1 楼 guobosheng 2010-06-23  
楼主你好,你代码中的
static {
    //加载Lua5.1.dll, 因为LuaJava最后还是要调用Lua的东西
    System.loadLibrary("lua5.1");
}

要加载Lua5.1.dll之前要做些什么准备?

我运行你的代码出错:no lua5.1.dll in java.library.path ,望指教!

详细:
java.lang.UnsatisfiedLinkError: no lua5.1.dll in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1709)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at Hello.<clinit>(Hello.java:19)
Exception in thread "main"

相关推荐

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

    Java调用Lua脚本是一种常见的跨语言交互技术,特别是在游戏开发和自动化脚本编写中。本文将详细介绍如何在Java环境中使用LuaJava库进行交互,并在Linux系统上进行安装和编译。 首先,让我们理解LuaJava。LuaJava是...

    Lua脚本语言中文教程.pdf

    这种理念使得Lua成为了一个高效的脚本语言,适用于多种开发环境。 最后,这本书的翻译和校对是由***的朋友们共同努力的结果。参与翻译和校对的人员被记录在名为thanks.lua的文件中,体现了开源和协作精神在编程社区...

    Jill——Java编写的Lua脚本引擎

    Java对象可以通过`JillEngine.registerJavaObject()`注册到Lua环境,然后在Lua脚本中使用。反之,Lua的值也可以通过`JillEngine.getGlobal()`获取到Java世界。 5. **错误处理**:在运行Lua脚本时,可能会遇到语法...

    Java学习资料-Spring Boot - 结合 Redis 使用 Lua脚本

    首先,让我们深入了解一下使用Lua脚本在高并发场景中的价值。在并发环境中,数据一致性是非常关键的。Lua脚本的原子性操作特性使得它成为解决这类问题的理想选择。当多线程或多个客户端同时访问同一数据时,Lua脚本...

    nodemcu lua脚本语言开发工具

    总结,nodemcu lua脚本语言开发涉及到固件管理、工具使用、文档查阅和编程环境搭建等多个环节。通过熟悉这些知识,开发者可以高效地进行nodemcu项目开发,利用lua的简洁性和易读性,快速实现物联网应用。在实践中,...

    luajava-x32-x64.zip

    经过测试,这些文件已被验证为可用,对于需要在Java项目中使用Lua功能的开发者来说,这是一个非常实用的资源。 首先,我们来了解一下luajava的核心概念。luajava是基于LuaJIT或Lua的一个Java绑定库,它的主要作用是...

    Javaweb中调用lua的插件

    这个JAR文件可以被JavaWeb应用引入,以便在Servlets、JSP或其他Java组件中使用lua的功能。通过`java.lang.reflect.Method`和`java.lang.invoke.MethodHandle`等Java反射机制,可以动态地调用Lua函数,实现动态脚本...

    luajava实例及jar包,dll动态链接库

    LuaJava是将Lua脚本语言与Java平台紧密结合的一个开源项目,它允许在Java程序中无缝地嵌入和执行Lua代码,从而实现灵活的脚本化功能。这个技术尤其适用于游戏开发、自动化测试、配置管理等领域,因为它提供了快速...

    luajava-1.1-x64-lua51

    2. **初始化Lua环境**:在Java代码中创建LuaState对象,这是执行Lua脚本的上下文。 3. **注册Java方法**:使用LuaState的函数将Java方法暴露给Lua,以便在Lua脚本中调用。 4. **执行Lua脚本**:调用LuaState的相应...

    LuaJava5.1

    使用LuaJava,开发者无需了解底层的C/C++接口,而是可以直接在Java环境中加载和运行Lua脚本,极大地简化了跨语言交互的过程。 LuaJava的源代码提供给了开发者深入研究和定制的可能性。通过查看和分析源代码,我们...

    Lua-1.0.113 luajava

    3. 示例代码或文档,展示如何在Lua中使用Java API。 4. 配置文件,可能包含LuaJIT和LuaJava的设置选项。 总的来说,Lua-1.0.113 luajava是结合了Lua的灵活性和Java的高性能的一个解决方案,为开发者提供了一种高效...

    浅析android手游lua脚本的加密与解密(番外篇之反编译的对抗)

    - **背景**:2018年腾讯游戏安全竞赛中的一项挑战,题目要求选手通过逆向工程分析出使用Lua脚本的游戏逻辑。 - **技术细节**:该题目的难点在于Lua字节码被进行了特殊处理,包括修改文件头以及对字节码进行了简单的...

    luajava.zip

    LuaJava是一个强大的工具,它将Lua脚本语言与Java环境紧密地结合起来,使得开发者可以在Java应用程序中无缝地使用Lua脚本进行逻辑处理和扩展功能。在本文中,我们将深入探讨LuaJava的核心特性、安装与配置、使用方法...

    lua插件包,帮助你搭建lua-java项目

    - **高性能**:Lua解释器运行速度快,对资源占用少,适合在有限的硬件环境中使用。 - **灵活性**:Lua支持面向过程、面向对象和函数式编程,可以根据需求灵活选择编程风格。 5. Lua在游戏开发中的应用: Lua因其...

    luajava-1.1.0

    luajava-1.1.0是一个专门用于连接Lua脚本语言和Java平台的库,它为开发者提供了在Java应用程序中运行Lua代码的能力,同时也允许Lua程序调用Java类和方法,实现了两者的无缝集成。这一强大的工具广泛应用于游戏开发、...

    lua脚本编程语言,需要的应该也是很迫切的

    通过深入学习Lua,不仅可以提升个人技能,还能够开拓更多的职业可能性,特别是在那些高度依赖脚本语言的领域。 总之,Lua脚本编程语言以其独特的魅力吸引着越来越多的开发者。无论你是初学者还是经验丰富的程序员,...

    luajava1.1 64位版本和32位版本

    luajava是一款将Lua脚本语言与Java平台紧密集成的工具,它允许在Java应用程序中无缝地执行Lua代码,同时也支持从Lua调用Java对象和方法,极大地拓展了Java应用的可扩展性和灵活性。本文将详细探讨luajava的64位版本...

Global site tag (gtag.js) - Google Analytics