LuaとJavaの相互運用の簡単な解決策---L uaJavaBridge

8637 ワード

私たちは物を書くときにluaの中でjavaコードを呼び出すことに遭遇します.もちろんこれはJNIでできるに違いありませんが、もっと便利な方法があります.LuaJavaBridge
一、luajの主な特徴
*     Lua    Java Class Static Method
*    Java    ,   int/float/boolean/String/Lua function       
*     Lua function         Java,   Java    Lua function    
*     Java    Lua      ,          Lua function

luajの機能は簡単ですが、さまざまなSDKを統合するには完全にニーズを満たしています.
二、luaj用法例
Java     
    public static float getNum(float n) {
        return n;
    }

-- Java     
local className = "com/qeeplay/frameworks/CheShi"
--     Java    
local method = 'getDisplayWidth'
--    Java        
local n = 10
local args = {
     n
}
--    Java   
local _, screenwidth = luaj.callStaticMethod(className, method, args)

三、luaj実現原理luajの核心目標は二つある:LuaからJavaを呼び出し、JavaからLuaを呼び出す.整理すると以下のようになります
*          Java   
*       ,   Java        
*   Lua function         Java   
*   Java       Lua function

四、指定されたJavaメソッドを検索して呼び出す
JNIは、指定したClassを検索するためのFindClass()メソッドを提供しているので、luaj.callStaticMethod()の最初のパラメータは、呼び出すJava Classの完全なクラス名(クラス名の「.」を「/」に置き換える)です.指定されたClassが見つかったら、JNIのGetStaticMethodID()メソッドを使用して、静的メソッドの名前と署名を指定することを前提として、このクラスの指定された静的メソッドを見つけることができます.
署名とは,Javaメソッドのパラメータタイプと戻りタイプ定義を指す.例えば、前述のサンプルコードのGameInterface_doBilling()メソッドの署名は(Ljava/lang/String;ZZZI)Vである.Javaメソッド署名の具体的な定義については、JNI Type Signaturesを参照してください.ここでluajは呼び出しパラメータに基づいてメソッド署名を自動的に推測できるので、例では署名例でパラメータを指定していません.
local args = {n}

luajはこのパラメータに基づいて,正しいメソッド署名を構築する.注意ここではLuaでは1つの数値が整数であるか浮動小数点数であるかを正確に判断することはできないので,luajはメソッド署名を推測する際に,すべての数値が浮動小数点数であると仮定する.次の呼び出しは間違っています
public static int getNum(int n) {
  return n;
}
-- Java     
local className = "com/qeeplay/frameworks/CheShi"
--     Java    
local method = 'getDisplayWidth'
--    Java        
local n = 10
local args = {
     n
}
--    Java   
local _, screenwidth = luaj.callStaticMethod(className, method, args)

これではだめなので、この時は自分で署名を定義します.
次に、正しい例を示します.
public static int getNum(int n) {
  return n;
}
-- Java     
local className = "com/qeeplay/frameworks/CheShi"
--     Java    
local method = 'getDisplayWidth'
--    Java        
local n = 10
local args = {
     n
}
--     --   : [I]nteger--    : [I]nt
local sig = "(I)I"
--    Java   
local _, screenwidth = luaj.callStaticMethod(className, method, args,sig)

署名は「(順番に並べられたパラメータタイプ)戻り値タイプ」のフォーマットを使用します.いくつかの例は次のとおりです.
                                             
()V                               : ,   : 
(I)V                              :int,   : 
(Ljava/lang/String;)Z             :   ,   :   
(IF)Ljava/lang/String;            :  、   ,   :   

ここには、Java署名文字列の種類が異なります.
                      
I                         ,   Lua function
F                          
Z                          
Ljava/lang/String;         
V                       Void  ,        Java         

JavaメソッドでLua functionを受信するパラメータはintタイプとして定義する必要があります
五、呼び出し結果をチェックし、Javaメソッドから戻り値を取得する
uajがJavaメソッドを呼び出すと、さまざまなエラーが発生する可能性があるため、luajはLua呼び出しコードがJavaメソッドが正常に呼び出されたかどうかを決定するメカニズムを提供します.luaj.callStaticMethod()は、次の2つの値を返します.
*     ,      true,      Java       (   )。
*     ,      false,         。

次のコードは、戻り結果をチェックし、戻り値を取得する方法を示します:javaコード
public static int AddTwoNumbers(final int number1, final int number2) {
  return number1 + number2;
}

Luaコード
local args = {2, 3}
local sig = "(II)I"
local ok, ret = luaj.callStaticMethod(className, "AddTwoNumbers", args, sig)

if not ok then
print("luaj error:", ret)
else
print("ret:", ret) --    ret: 5
end

エラーコードの定義は次のとおりです.
                                  
-1                                        
-2                               
-3                                   
-4                          Java           
-5                          Java      
-6                          Java      

六、Lua functionをパラメータとしてJavaメソッドに渡す
Lua仮想マシンでは、Lua functionが値として保存されます.しかし、この値はJavaに直接使用できないため、luajはLua functionリファレンステーブルを作成しました.Lua functionがJavaに渡されると、このfunctionに対応する値が参照テーブルに存在し、一意の参照ID(整数)が得られる.Javaコードはこの参照IDを入手すると、このLua functionを簡単に呼び出すことができます.JavaメソッドでLua functionを受信するパラメータはintタイプの例として定義する必要があります
public static int getNum(int n) {
  return n;
}
local function callback(result)
     ---    
end
-- Java     
local className = "com/qeeplay/frameworks/CheShi"
--     Java    
local method = 'getDisplayWidth'
--    Java        
local args = {
     callback
}
--     --   : [I]nteger--    : [I]nt
local sig = "(I)I"
--    Java   
local _, screenwidth = luaj.callStaticMethod(className, method, args,sig)