Help us understand the problem. What is going on with this article?

NLuaを使ってみる 2

More than 1 year has passed since last update.

前回、関数を登録する際に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を実行しなければならない、ということではないはず。
もう少し詳しく調べてみたい気もするけど、テーブルをうまく扱うのが目的ではなく、他にやりたいことがあるので、今回はこのあたりで妥協。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away