LuaJ 调用 Lua require加载的lib

 最近要把Lua编写的优化算法集成到JavaWeb项目里,搜了一圈,大多人推荐Luaj,研究了一圈发现基本调用是可以的,但是如果lua代码中出现require其他lua文件,会提示找不到,折腾了三天,最后在一位同学的博客下找到了灵感。经过了小小的改动,原因是版本问题。

感谢:原著地址icon-default.png?t=L9C2https://www.cnblogs.com/softidea/p/5285939.html这个例子中,不仅包括Java调用Lua,也包括Lua调用java

环境配置:

JDK:1.8

Lua:5.1

LuaJ :2.0.3

java:

package org.example;

import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.JsePlatform;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
//        test1();
//        test2();
//        test3();
//        test4();
        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("D:\\LuaJTest\\src\\main\\java\\org\\example\\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);
    }


    private static void test4() {
        // lua脚本文件所在路径
        String luaPath = "D:\\LuaJTest\\src\\main\\java\\org\\example\\test3.lua";
        Globals globals = JsePlatform.standardGlobals();
    // 加载脚本文件script/test.lua,并编译
        globals.loadfile(luaPath).call();

// 获取函数:pi()
        LuaValue func = globals.get(LuaValue.valueOf("pi"));
// 执行pi()方法获取圆周率
        double pi = func.call().todouble();
        System.out.println("圆周率:" + pi);
    }

    private static void test3() {
        String luaPath = "D:\\LuaJTest\\src\\main\\java\\org\\example\\test_custom_library.lua";
        Globals globals = JsePlatform.standardGlobals();

        //加载自定义函数库
        globals.load(new MyLibrary());
        LoadState.install(globals);
        LuaC.install(globals);

        // 加载脚本文件script/test.lua,并编译
        globals.loadfile(luaPath).call();
    }

    private static void test2() {
        // lua脚本文件所在路径
        String luaPath = "D:\\LuaJTest\\src\\main\\java\\org\\example\\test.lua";
        Globals globals = JsePlatform.standardGlobals();
// 加载脚本文件script/test.lua,并编译
        globals.loadfile(luaPath).call();

// 获取函数:pi()
        LuaValue func = globals.get(LuaValue.valueOf("pi"));
// 执行pi()方法获取圆周率
        double pi = func.call().todouble();
        System.out.println("圆周率:" + pi);

// 获取带参函数circle_area()
        LuaValue func1 = globals.get(LuaValue.valueOf("circle_area"));
// 执行circle_area方法,传入double类型的半径参数
        double area = func1.call(LuaValue.valueOf(3.0)).todouble();
// 打印lua函数回传的数据
        System.out.println("半径为3.0的圆形面积为:" + area);
    }

    private static void test1() {
        String luaStr = "print 'Hello World!'";
        Globals globals = JsePlatform.standardGlobals();
        LuaValue lv = globals.load(luaStr);
        lv.call();
    }
}
package org.example;

import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;

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:

---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by a1599.
--- DateTime: 2021/10/31 15:18
---
--注意查找目录是从工程的根目录开始的
require ("D:\\LuaJTest\\src\\main\\java\\org\\example\\div")
--引用java提供的方法,则直接写java的类名就好
jlib = require ("org.example.Math")
-- 模板方法
function genkey()
    tm = jlib.timestamp()
    a = div(tm, 1000)
    b = div(tm, 400)
    r = jlib.bitxor(a, b)
    return r
end
--module(..., package.seeall)
-- 这里也可以require java提供的模块,本例没用到
function div(a, b)
    return math.floor(a / b)
end

重点来了!!!

在被require的lua文件中,不需要

module(..., package.seeall)

在gen.lua中require一定要全路径,并且不带后缀(.lua)。用跟目录IDE也会显示正确,但是会加载不到

require ("D:\\LuaJTest\\src\\main\\java\\org\\example\\div")
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值