当前位置: 首页 > 后端技术 > Java

Java+Lua=炸弹王!!

时间:2023-04-01 17:41:13 Java

我们在写东西的时候总会遇到lua中的java代码。当然,这可以用JNI来完成,但还有更方便的方式——LuaJavaBridge。1.luaj的主要特点*可以从Lua调用Java类静态方法*调用Java方法时,支持int/float/boolean/String/Lua函数五种参数类型*可以将Lua函数作为参数传递给Java,让JavasaveitReferenceofLuafunction*可以从Java中调用Lua的全局函数,也可以调用引用指向的Lua函数。Luaj的功能很简单,但是已经完全满足了集成各种SDK的需求。2.Luaj使用示例Java方法原型publicstaticfloatgetNum(floatn){returnn;}localclassName="com/qeeplay/frameworks/CheShi"localmethod='getDisplayWidth'localn=10localargs={n}local_,screenwidth=luaj.callStaticMethod(className,method,args)3.Luaj实现原理luaj有两个核心目标:从Lua调用Java,从Java调用Lua。梳理以下几点*查找并调用指定的Java方法*查看调用结果并获取Java方法的返回值*将Lua函数作为参数传递给Java方法*在Java方法中调用Lua函数推荐一个开源免费的SpringBoot最全教程:https://github.com/javastacks/spring-boot-best-practice4.查找并调用指定Java方法JNI提供FindClass()方法查找指定Class,所以luaj.callStaticMethod()是要调用的Java类的全类名(类名中的“.”要用“/”代替)。找到指定的Class后,使用JNI的GetStaticMethodID()方法找到该类的指定静态方法,前提是提供静态方法的名称和签名。所谓签名是指Java方法的参数类型和返回类型定义。例如,前面示例代码中GameInterface_doBilling()方法的签名是(Ljava/lang/String;ZZI)V。Java方法签名的具体定义可以参考:JNITypeSignatures。这里要说的是,luaj是可以根据调用参数自动猜出方法签名的,所以例子中我们没有写签名。例子中指定了参数localargs={n}1luaj。根据这个参数,将构造出正确的方法签名。注意,这里要说的是,Lua中没有办法准确判断一个值是整数还是浮点数,所以luaj在猜测方法签名的时候,假设所有的值都是浮点数点数。所以下面的调用会报错publicstaticintgetNum(intn){returnn;}localclassName="com/qeeplay/frameworks/CheShi"localmethod='getDisplayWidth'localn=10localargs={n}local_,screenwidth=luaj.callStaticMethod(className,method,args)是不行的,所以这个时候我们要自己定义签名。正确的例子如下:publicstaticintgetNum(intn){returnn;}localclassName="com/qeeplay/frameworks/CheShi"localmethod='getDisplayWidth'localn=10localargs={n}localsig="(I)I"local_,screenwidth=luaj.callStaticMethod(className,method,args,sig)signatureusing"(Arrangedparametertypesinsequence)formatofreturnvaluetype",几个例子如下:SignatureExplanation()V参数:无,返回值:无(I)V参数:int,返回值:无(Ljava/lang/String;)Z参数:字符串,返回值:布尔值(IF)Ljava/lang/String;参数:整数,浮点数,返回值:字符串12345下面是不同类型对应的Java签名字符串:类型名类型IInteger,或者Lua函数FFloatZBooleanLjava/语言/字符串;StringVVoid为空,仅用于指定不返回任何值的Java方法123456Java方法中接收Lua函数的参数必须定义为int类型5查看调用结果,从Java中获取返回值uajmethod调用Java方法,可能会出现各种错误,所以luaj提供了Lua调用代码判断Java方法是否成功的机制。调用luaj.callStaticMethod()将返回两个值:*成功时,第一个值为true,第二个值为Java方法的返回值(如果有)。*失败时,第一个值为false,第二个值为错误代码。以下代码显示了如何检查返回结果并获取返回值:javacodepublicstaticintAddTwoNumbers(finalintnumber1,finalintnumber2){returnnumber1+number2;}Luacodelocalargs={2,3}localsig="(II)I"localok,ret=luaj.callStaticMethod(className,"AddTwoNumbers",args,sig)ifnotokthenprint("luajerror:",ret)elseprint("ret:",ret)结束错误代码定义如下:错误代码描述-1不支持的参数类型或返回值类型-2签名无效-3未找到指定的方法-4Java方法执行过程中抛出异常-5Java虚拟机错误-6Java虚拟机报错6、将Lua函数作为参数传递给Java方法在Lua虚拟机中,Lua函数是以值的形式保存的。但是这个值不能被Java直接使用,所以luaj做了一个Lua函数引用表。当一个Lua函数被传递给Java时,这个函数对应的值会存储在引用表中,并得到一个唯一的引用ID(整数)。Java代码得到引用ID后,就可以轻松调用Lua函数了。因此,Java方法中接收Lua函数的参数必须定义为int类型,例如:publicstaticintgetNum(intn){returnn;}localfunctioncallback(result)endlocalclassName="com/qeeplay/frameworks/CheShi"localmethod='getDisplayWidth'localargs={callback}localsig="(I)I"local_,screenwidth=luaj.callStaticMethod(className,method,args,sig)版权声明:本文为CSDN原创文章博主“Vincent__Lee”,遵循CC4.0BY-SA版权协议,转载请附上原文链接和本声明。