当前位置:   article > 正文

LuaJ 调用 Lua require加载的lib_android lua脚本在require("libmylib")

android lua脚本在require("libmylib")

 最近要把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:

  1. package org.example;
  2. import org.luaj.vm2.Globals;
  3. import org.luaj.vm2.LoadState;
  4. import org.luaj.vm2.LuaValue;
  5. import org.luaj.vm2.compiler.LuaC;
  6. import org.luaj.vm2.lib.jse.JsePlatform;
  7. /**
  8. * Hello world!
  9. *
  10. */
  11. public class App
  12. {
  13. public static void main( String[] args )
  14. {
  15. // test1();
  16. // test2();
  17. // test3();
  18. // test4();
  19. long key = getKey();
  20. System.out.println(key);
  21. System.out.println(getKeyJava());
  22. }
  23. public static long getKey() {
  24. //获取一个lua的运行环境,lua虚拟机应该就在这里了
  25. //lua是个弱类型语言,在java里,所有从lua获得的,或者要传递给lua的,都是LuaValue对象
  26. LuaValue _G = JsePlatform.standardGlobals();
  27. //执行gen.lua脚本
  28. //_G.get("dofile")获取dofile方法的对象
  29. //get其实是获取table值的方法,dofile就是全局table的一个值
  30. //对于Function类型的对象可以用call方法去调用,参数就是lua方法需要的参数,但是一定要转换成LuaValue类型
  31. _G.get("dofile").call(LuaValue.valueOf("D:\\LuaJTest\\src\\main\\java\\org\\example\\gen.lua"));
  32. //上一句执行完以后,gen.lua中的genkey函数就在全局变量中了,
  33. //可以这样直接调用
  34. LuaValue key = _G.get("genkey").call();
  35. return key.checklong();
  36. }
  37. //用java实现的,比较用
  38. //value = (int)(timestamp / 1000 ) ^ (int)(timestamp / 400)
  39. public static long getKeyJava() {
  40. long tm = System.currentTimeMillis() / 1000;
  41. return (tm / 1000) ^ (tm / 400);
  42. }
  43. private static void test4() {
  44. // lua脚本文件所在路径
  45. String luaPath = "D:\\LuaJTest\\src\\main\\java\\org\\example\\test3.lua";
  46. Globals globals = JsePlatform.standardGlobals();
  47. // 加载脚本文件script/test.lua,并编译
  48. globals.loadfile(luaPath).call();
  49. // 获取函数:pi()
  50. LuaValue func = globals.get(LuaValue.valueOf("pi"));
  51. // 执行pi()方法获取圆周率
  52. double pi = func.call().todouble();
  53. System.out.println("圆周率:" + pi);
  54. }
  55. private static void test3() {
  56. String luaPath = "D:\\LuaJTest\\src\\main\\java\\org\\example\\test_custom_library.lua";
  57. Globals globals = JsePlatform.standardGlobals();
  58. //加载自定义函数库
  59. globals.load(new MyLibrary());
  60. LoadState.install(globals);
  61. LuaC.install(globals);
  62. // 加载脚本文件script/test.lua,并编译
  63. globals.loadfile(luaPath).call();
  64. }
  65. private static void test2() {
  66. // lua脚本文件所在路径
  67. String luaPath = "D:\\LuaJTest\\src\\main\\java\\org\\example\\test.lua";
  68. Globals globals = JsePlatform.standardGlobals();
  69. // 加载脚本文件script/test.lua,并编译
  70. globals.loadfile(luaPath).call();
  71. // 获取函数:pi()
  72. LuaValue func = globals.get(LuaValue.valueOf("pi"));
  73. // 执行pi()方法获取圆周率
  74. double pi = func.call().todouble();
  75. System.out.println("圆周率:" + pi);
  76. // 获取带参函数circle_area()
  77. LuaValue func1 = globals.get(LuaValue.valueOf("circle_area"));
  78. // 执行circle_area方法,传入double类型的半径参数
  79. double area = func1.call(LuaValue.valueOf(3.0)).todouble();
  80. // 打印lua函数回传的数据
  81. System.out.println("半径为3.0的圆形面积为:" + area);
  82. }
  83. private static void test1() {
  84. String luaStr = "print 'Hello World!'";
  85. Globals globals = JsePlatform.standardGlobals();
  86. LuaValue lv = globals.load(luaStr);
  87. lv.call();
  88. }
  89. }
  1. package org.example;
  2. import org.luaj.vm2.LuaValue;
  3. import org.luaj.vm2.lib.OneArgFunction;
  4. import org.luaj.vm2.lib.TwoArgFunction;
  5. import org.luaj.vm2.lib.ZeroArgFunction;
  6. public class Math extends OneArgFunction {
  7. //lua的方法都是闭包,在java中一定是用类对象与之对应的。
  8. //于是call这个方法就是调用闭包使用所调用的方法,必须实现
  9. public LuaValue call(LuaValue modname) {
  10. //这是类在lua里是一个模块,也就是个函数包,在lua里也就是一个table
  11. //table的每一个元素是一个函数(闭包而已)
  12. //这个lib就是一个table,用来存放各个lua模块方法
  13. LuaValue lib = tableOf();
  14. //设置timestamp方法
  15. lib.set("timestamp", new lua_timestamp());
  16. //设置异或方法
  17. lib.set("bitxor", new lua_bitxor());
  18. //这里不确定:env是该类的环境参数,暂时没研究这一句的作用,本例中不设置也没关系
  19. // env.set(modname.checkjstring(), lib);
  20. return lib;
  21. }
  22. static class lua_timestamp extends ZeroArgFunction {
  23. public LuaValue call() {
  24. return LuaValue.valueOf(System.currentTimeMillis() / 1000);
  25. }
  26. }
  27. static class lua_bitxor extends TwoArgFunction {
  28. public LuaValue call(LuaValue a, LuaValue b) {
  29. //lua传进来参数都是LuaValue的,java使用的时候需要使用相应的check方法转为本地变量
  30. long pa = a.checklong();
  31. long pb = b.checklong();
  32. long r = pa ^ pb;
  33. //返回的时候需要用valueOf方法转为LuaValue类型
  34. return LuaValue.valueOf(r);
  35. }
  36. }
  37. }

Lua:

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

重点来了!!!

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

module(..., package.seeall)

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

require ("D:\\LuaJTest\\src\\main\\java\\org\\example\\div")
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/904768
推荐阅读
相关标签
  

闽ICP备14008679号