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