Java調用Lua

前言
最近一款遊戲開發中,客戶端基於lua語言開發,爲了方便客戶端調用原型數據,全部的原型數據都以lua表格的形式存放;對於服務器端的java語言就須要解析出lua中的數據, 轉換爲java對象。html

橋接的選擇
網上大體搜索了一下,用的比較普遍的是下面這兩款:
1.luajava 官網:http://luaforge.net/projects/luajava/
2.luaj 官網:http://www.luaj.org/luaj/3.0/README.htmljava

看luajava的官網上支持的lua寫的是lua5,lua如今的最新版本已經到5.3了,應該是很久沒有更新了,同時也能夠看github上的源碼luajava,最近的一次改動是在3年前;相比較luaj雖然沒有提供最新的lua5.3支持,可是已經提供到了lua5.2的支持,明顯更加活躍。
另一點就是luajava在使用中是依賴於dll(動態連接庫)的,而luaj是純java語言git

綜上最終選擇luaj做爲橋接器
maven引入:github

<dependency>
    <groupId>org.luaj</groupId>
    <artifactId>luaj-jse</artifactId>
    <version>2.0.3</version>
</dependency>

實例
1.準備一個存放數據的lua文件TbTest.lua,存放路徑D:/Datawindows

TbTest = {
      [1] = {1,[[name1]],{1,2},
      },
      [2] = {2,[[name2]],
      },
}

準備了一張表數據,裏面準備了int類型,string類型以及table類型服務器

2.提供lua對外的接口LuaToJavaBridge.luamaven

LuaToJavaBridge = {}

function LuaToJavaBridge.getData(dbName,dataId,fieldIndex)
     require(dbName)
     local dbData=_G[dbName]
     
     local lineData=dbData[dataId]
     return lineData[fieldIndex]
end

提供了一個lua類LuaToJavaBridge,方法getData的3個參數分別是:表名,表Id和字段編號
require(dbName) 引入須要的lua文件編輯器

3.提供一個java調用lua的類JavaToLuaBridge測試

import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;

public class JavaToLuaBridge {

    private static LuaValue javaToLua;

    private JavaToLuaBridge() {

    }

    public static void init(String packagePath, String javaToLuaFile,
            String javaToLuaClass) {
        LuaValue _G = JsePlatform.standardGlobals();
        _G.get("package").set("path", packagePath);

        _G.get("dofile").call(LuaValue.valueOf(javaToLuaFile));
        javaToLua = _G.get(javaToLuaClass);
    }

    public static LuaValue getData(String dbName, int dataId, int fieldIndex) {
        LuaValue result = javaToLua.get("getData").call(
                LuaValue.valueOf(dbName), LuaValue.valueOf(dataId),
                LuaValue.valueOf(fieldIndex));
        return result;
    }
}

init方法,提供一個lua的運行環境,lua是弱語言,全部傳遞給lua,或者從lua獲取的都是LuaValue對象
_G.get(「package」).set(「path」, packagePath); 用來設置lua數據的位置,這裏能夠設置成D:/Data/?.lua
_G.get(「dofile」).call(LuaValue.valueOf(javaToLuaFile));獲取dofile的對象,而後加載LuaToJavaBridge.lua文件
最後獲取LuaToJavaBridge.lua文件中的類文件ui

4.測試

public static void main(String[] args) {
        JavaToLuaBridge.init("D:/Data/?.lua", "LuaToJavaBridge.lua",
                "LuaToJavaBridge");

        int id = JavaToLuaBridge.getData("TbTest", 1, 1).checkint();
        String name = JavaToLuaBridge.getData("TbTest", 1, 2).checkjstring();

        LuaTable table = JavaToLuaBridge.getData("TbTest", 1, 3).checktable();
        int len = table.length();
        for (int i = 1; i <= len; i++) {
            int tv = table.get(i).checkint();
            System.out.println(tv);
        }
        System.out.println("id = " + id + ",name = " + name);
    }

首先初始化,而後獲取數據文件中的數據,對於int和string類型,分別調用checkint()和checkjstring()方法轉化爲對於的java類型;對於table類型須要checktable(),須要注意的是全部的lua表下標都是從1開始的。

在此期間遇到一個問題,讓我迷惑了半天,剛剛還運行好好的,不一會就報下面這個錯了:

Exception in thread "main" org.luaj.vm2.LuaError: LuaToJavaBridge.lua:1: unexpected symbol
    at org.luaj.vm2.LuaValue.error(Unknown Source)
    at org.luaj.vm2.lib.BaseLib$BaseLibV.invoke(Unknown Source)
    at org.luaj.vm2.lib.VarArgFunction.call(Unknown Source)
    at com.luaj.luajTest.JavaToLuaBridge.init(JavaToLuaBridge.java:20)
    at com.luaj.luajTest.JavaToLuaBridge.main(JavaToLuaBridge.java:32)

大意就是裏面出現了意想不到的符號;
緣由:使用了記事本進行修改,記事本修改後保存的lua文件只是UTF-8編碼,可是通常來講,lua是不支持有BOM的,lua文件應該保存爲UTF-8無BOM類型,而windows記事本的UTF-8是有BOM的,這就會形成錯誤。因此,文件存儲時格式通常選擇UTF-8無BOM格式
BOM: Byte Order Mark
UTF-8 BOM又叫UTF-8 簽名,其實UTF-8 的BOM對UFT-8沒有做用,是爲了支援UTF-16,UTF-32才加上的BOM,BOM簽名的意思就是告訴編輯器當前文件採用何種編碼,方便編輯器識別,可是BOM雖然在編輯器中不顯示,可是會產生輸出,就像多了一個空行。

總結 整體來講使用起來仍是挺方便的,以上只是一個簡單的例子,涉及的數據類型也沒有全,不過整體的結構能夠參考一下;其實若是想更加熟練的使用luaj,仍是要對lua自己比較熟悉。

相關文章
相關標籤/搜索