LoginSignup
1
2

More than 5 years have passed since last update.

NLuaを使ってみる 2

Posted at

前回、関数を登録する際にRegisterFunctionを使っていたが、Luaに直接C#のインスタンスを渡せるらしいので、その方法を使ってみた。
ついでなので、テーブルのやり取りもやってみた。

テストコード
static void Main(string[] args)
{
    using (NLua.Lua instance = new NLua.Lua())
    {
        instance["cls1"] = new Class(instance, "def");
        instance["cls2"] = new Class(instance, "ghi");

        instance.DoString("tbl = cls1:func1()");
        instance.DoString("for i, j in pairs(tbl) do print(i, j) end");

        instance.DoString("tbl = cls2:func1()");
        instance.DoString("for i, j in pairs(tbl) do print(i, j) end");

        instance.DoString("cls1:func2(tbl)");
        instance.DoString("cls2:func2(tbl)");
    }
}

public class Class
{
    private readonly NLua.Lua instance;

    private string str;

    public Class(NLua.Lua instance, string str)
    {
        this.instance = instance;
        this.str = str;
    }

    public object func1()
    {
        Dictionary<string, object> dic = new Dictionary<string, object>();

        dic["a"] = 12.34;
        dic["x"] = str;

        return (CreateLuaTable(dic));
    }

    public void func2(NLua.LuaTable table)
    {
        Console.WriteLine("***");

        foreach (string key in table.Keys)
        {
            Console.WriteLine(key + " : " + table[key] + " ( " + table[key].GetType().ToString() + " )");
        }

        Console.WriteLine("***");
    }

    protected NLua.LuaTable CreateLuaTable(Dictionary<string, object> dic)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("return({");

        foreach (var v in dic)
        {
            if (typeof(string) == v.Value.GetType())
            {
                sb.Append(v.Key + "=\"" + v.Value + "\",");
            }
            else
            {
                sb.Append(v.Key + "=" + v.Value + ",");
            }
        }

        sb.Append("})");

        return ((NLua.LuaTable)(instance.DoString(sb.ToString())[0]));
    }
}
結果
a       12.34
x       def
a       12.34
x       ghi
***
a : 12.34 ( System.Double )
x : ghi ( System.String )
***
***
a : 12.34 ( System.Double )
x : ghi ( System.String )
***

Luaにインスタンスを渡せば、名前空間を維持したままで使うことができる。
ただし、変数と関数で.:を使い分ける必要がある。

テーブルの扱いはちょっと面倒。
C#で受け取るだけならNLua.LuaTableを引数にすればいいが、C#から返すのはかなり面倒。うまいやり方を見つけられなかった。
とりあえず、今回はDoStringでテーブルを作るメソッドを作った。また、その際は、別のLuaインスタンスからテーブルを持ってくると例外が発生するので、コンストラクタで受け取ったLuaインスタンスでDoStringを行っている。

例外が発生するのはpairsのあたりだが、例えばLuaインスタンスを2つ作り、その間でテーブルを移動してpairsを行っても例外は発生しないので、必ずテーブルを作ったインスタンスの中でpairsを実行しなければならない、ということではないはず。
もう少し詳しく調べてみたい気もするけど、テーブルをうまく扱うのが目的ではなく、他にやりたいことがあるので、今回はこのあたりで妥協。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2