luaj:初探


luaj是lua的一个java版本的实现。使用luaj可以在java程序中允许lua程序。这给java带来了脚本功能。luaj对javase 和Android 都提供了支持。

下面第一个例子,使用java加载lua脚本并执行。

main.java 文件内容:

               String script = "hello.lua";
		
		// create an environment to run in
		//初始化lua运行时环境
		Globals globals = JsePlatform.standardGlobals();
		
		// Use the convenience function on Globals to load a chunk.
		//通过Globals加载lua脚本
		LuaValue chunk = globals.loadfile(script);
		
		// Use any of the "call()" or "invoke()" functions directly on the chunk.
		//运行lua脚本
		chunk.call( LuaValue.valueOf(script) );
hello.lua 文件内容:

 print("hello  luaj !!!")

在两种语言交互使用中,就存在几个方面的内容:1 -两种语言中基本数据类型的映射    2 -两种语言中函数的相互调用  3- 语言的内存管理

在这篇中我们主要关注luaj怎么来表达lua语言以及luaj的使用。


在Luaj中我们首先关注的类为Globals,该类用来初始化lua 虚拟机以及加载lua脚本。


	/**
	 * Create a standard set of globals for JSE including all the libraries.
	 * 
	 * @return Table of globals initialized with the standard JSE libraries
	 * @see #debugGlobals()
	 * @see org.luaj.vm2.lib.jse.JsePlatform
	 * @see org.luaj.vm2.lib.jme.JmePlatform
	 */
	public static Globals standardGlobals() {
		Globals globals = new Globals();
		globals.load(new JseBaseLib());
		globals.load(new PackageLib());
		globals.load(new Bit32Lib());
		globals.load(new TableLib());
		globals.load(new StringLib());
		globals.load(new CoroutineLib());
		globals.load(new JseMathLib());
		globals.load(new JseIoLib());
		globals.load(new JseOsLib());
		globals.load(new LuajavaLib());
		LoadState.install(globals);
		LuaC.install(globals);
		return globals;		
	}

在创建Globals对象的同时,初始化了lua的基本功能。例如基本函数,基本库函数table等.


Globals 继承 LuaValue 对象,LuaValue对象用来表示在Lua语言的基本数据类型。比如:Nil,Number,String,Table,userdata,Function等。尤其要注意LuaValue也表示了Lua语言中的函数。所以,对于Lua语言中的函数操作都是通过LuaValue来实现的。

1-  lua语言调用java方法

下面通过一个在lua中调用java的函数例子来演示,该例子来自官方。

main.lua  类:

                String script = "hyperbolic.lua";
		Globals globals = new Globals();
		globals.load(new JseBaseLib());
		globals.load(new PackageLib());
		globals.load(new Bit32Lib());
		globals.load(new TableLib());
		globals.load(new StringLib());
		globals.load(new CoroutineLib());
		globals.load(new JseMathLib());
		globals.load(new JseIoLib());
		globals.load(new JseOsLib());
		globals.load(new LuajavaLib());
		//加载自定义库
		globals.load(new hyperbolic());
		LoadState.install(globals);
		LuaC.install(globals);
		LuaValue chunk = globals.loadfile(script);
		chunk.call();

自定义java类,在lua中注册,并通过lua 语法来调用。

/**
 * Sample library that can be called via luaj's require() implementation.
 * 
 * This library, when loaded, creates a lua package called "hyperbolic" 
 * which has two functions, "sinh()" and "cosh()".
 *
 * Because the class is in the default Java package, it can be called using 
 * lua code such as:
 * 
 
 {@code 
 * require 'hyperbolic'
 * print('sinh',  hyperbolic.sinh)
 * print('sinh(1.0)',  hyperbolic.sinh(1.0))
 * }
* * When require() loads the code, two things happen: 1) the public constructor * is called to construct a library instance, and 2) the instance is invoked * as a java call with no arguments. This invocation should be used to initialize * the library, and add any values to globals that are desired. */ public class hyperbolic extends TwoArgFunction { /** Public constructor. To be loaded via require(), the library class * must have a public constructor. */ public hyperbolic() { } /** The implementation of the TwoArgFunction interface. * This will be called once when the library is loaded via require(). * @param modname LuaString containing the name used in the call to require(). * @param env LuaValue containing the environment for this function. * @return Value that will be returned in the require() call. In this case, * it is the library itself. */ public LuaValue call(LuaValue modname, LuaValue env) { LuaValue library = tableOf(); library.set( "sinh", new sinh() ); library.set( "cosh", new cosh() ); env.set( "hyperbolic", library ); env.get("package").get("loaded").set("hyperbolic", library); return library; } /* Each library function is coded as a specific LibFunction based on the * arguments it expects and returns. By using OneArgFunction, rather than * LibFunction directly, the number of arguments supplied will be coerced * to match what the implementation expects. */ /** Mathematical sinh function provided as a OneArgFunction. */ static class sinh extends OneArgFunction { public LuaValue call(LuaValue x) { return LuaValue.valueOf(Math.sinh(x.checkdouble())); } } /** Mathematical cosh function provided as a OneArgFunction. */ static class cosh extends OneArgFunction { public LuaValue call(LuaValue x) { return LuaValue.valueOf(Math.cosh(x.checkdouble())); } } }

hyperbolic.lua  脚本:

require 'hyperbolic'


print('hyperbolic', hyperbolic)
print('hyperbolic.sinh', hyperbolic.sinh)
print('hyperbolic.cosh', hyperbolic.cosh)

print('sinh(0.5)', hyperbolic.sinh(0.5))
print('cosh(0.5)', hyperbolic.cosh(0.5))

上面实现了在java语言中定义的java方法可以通过lua语言调用。


2 -java语言调用lua方法


在java语言中调用lua 语言中的hi()自定义函数,并传递参数some.   在java语言中获取全局hTable函数,并迭代里面的内容。

main.java 文件代码:

            Globals globals = JsePlatform.standardGlobals();
		//加载lua脚本,并编译
	    LuaValue luachuck = globals.load(new InputStreamReader(new FileInputStream(new File("hi.lua"))), "chunkname").call();
	    //在Globals获取全局函数hi,并传递参数调用
	    LuaValue func = globals.get(LuaValue.valueOf("hi"));
	    //在luaj中LuaValue映射了lua中的基本数据类型,包括函数
	    func.invoke(new LuaValue[]{LuaValue.valueOf(new Date().toString())});
	    
	    
	    LuaValue hTable = globals.get(LuaValue.valueOf("hTable"));
	    //迭代table结构
	    LuaValue k = LuaValue.NIL;
	    while ( true ) {
	       Varargs n = hTable.next(k);
	       if ( (k = n.arg1()).isnil() )
	          break;
	       LuaValue v = n.arg(1);
	       System.out.println("v:"+v.tostring());
	       LuaValue m = n.arg(2);
	       //把lua 结构转换成java结构
	       LuaTable tb = (LuaTable)CoerceLuaToJava.coerce(m, LuaTable.class);
	       System.out.println("m:"+tb.typename());
	    }

	

hi.lua 文件代码:

function  hi(some)
     print("every day  is  a  new  day:"..some)
end

hTable={
	[1]={"a","b","c"},
	[2]={"d","e","f"}
}

3  lua调用java中的对象,以及对象属性。

 

main.java文件内容:

	Globals globals = JsePlatform.standardGlobals();
		//加载lua脚本,并编译
	    LuaValue luachuck = globals.load(new InputStreamReader(new FileInputStream(new File("calljava.lua"))), "chunkname").call();

HiObject.java类文件:

public class HiObject 
{
	public  int a ;
	public static  int  b;
	
	public HiObject(int a) 
	{
		this.a = a;
	}
	public static void staticShowHiObject()
	{
		System.out.println("staticShowHiObject  b:"+b);	
	}
	public   void  showHiObject()
	{
		System.out.println("showHiObject  a:"+a);
	}
}

calljava.lua文件:

local hiObjecClazz = luajava.bindClass("test.HiObject")

hiObjecClazz.b =666

hiObjecClazz:staticShowHiObject()

local hiObject = luajava.newInstance("test.HiObject", 888);

hiObject:showHiObject()

4  java类对象传递通过参数传递到lua语言中

main.java文件:

		Globals globals = JsePlatform.standardGlobals();
		//加载lua脚本,并编译
	    LuaValue luachuck = globals.load(new InputStreamReader(new FileInputStream(new File("calljavaobject.lua"))), "chunkname").call();
	    
	    
	    //在Globals获取全局函数hi,并传递参数调用
	    LuaValue func = globals.get(LuaValue.valueOf("calljavaobjectfunc"));
	    
	    HiObject hiObject =new HiObject(999);
	    
	    LuaValue luaObject =CoerceJavaToLua.coerce(hiObject);
	    

	    func.invoke(new LuaValue[]{luaObject});

calljavaobject.lua文件:

function  calljavaobjectfunc(javaobject)
     javaobject:showHiObject()
end









你可能感兴趣的:(LuaJava)