NeoLua

提供: MonoBook
2018年8月15日 (水) 10:19時点におけるimported>Administratorによる版 (→‎C#で関数を追加する)
ナビゲーションに移動 検索に移動

NeoLuaとは、オープンソースの下で開発されている.NET Framework向けのLua実装である。

概要

.NET Framework向けのLua実装は多数存在するが、それらは本家LuaのDLLP/Invokeで呼び出すものが多い。

一方、NeoLuaは.NET向けに移植されたCLRでのピュア実装となっている。 つまりIronPythonなどと同じ系列である。 表向きの名前はNeoLuaであるが、内部的な名前空間は「Neo.IronLua」となっており、やはり「Iron〜」である。 NeoLuaはPortable Class LibraryPCL)環境でも何も考えずに一発で動くように作られている点がポイント高い。Xamarin系、MonoGame系では大活躍である。

NeoLuaは「純正Lua」ではなく「Lua互換品」となるためNeoLuaの公式サイトでも「100%の互換性はない」としている。互換性に問題があるようであればNLuaあたりを使ったほうがいいかもしれないが、NeoLuaの方が積極的にメンテナンスされており活況ではある。

使い方

インストール

  • NuGetからNeoLuaを入れろ。
  • 参照に「Microsoft.CSharp」を追加しろ。  ← これ重要(ダイナミック版を使う場合のみ必須)

ハロワ

まずは定番のハロワ。NeoLuaには2種類の実行環境がある。頭の固い人向けの静的版と、ユルユルな人向けのダイナミック版である。CreateEnvironmentメソッドの戻り値の型を、「var」(型推論)にすると静的版に、「dynamic」にするとダイナミック版になる。ダイナミック版はインテリセンスが効かない諸刃の剣であるが、ある程度慣れると圧倒的にこちらの方が便利かつ簡潔明瞭である。ちなみにダイナミック版のdochunkは小文字だぞ。

こういう書き方もできる。 「clr」で標準の名前空間にもアクセスできる。

            using (var lua = new Lua())
            {
                dynamic g = lua.CreateEnvironment();
                g.dochunk(@"
                    s = 'hello world';
                    clr.System.Console.WriteLine(s);
                ");
            }

dynamic変数を使わない方法だとSetMemberValue()だのCallMember()などのメソッドを使う。 この場合のDoChunkはパスカル記法だ。 ついでにまったく関係ないことだがLuaでの文字列連結は「..」だ。

            using (var lua = new Lua())
            {
                var env = lua.CreateEnvironment();
                env.DoChunk(@"
                    name = 'foo';
                    function Hello()
                        return 'hello ' .. name;
                    end
                ","test.lua");

                var ret1 = env.CallMember("Hello");
                Console.WriteLine(ret1.ToString());

                env.SetMemberValue("name", "bar");
                var ret2 = env.CallMember("Hello");
                Console.WriteLine(ret2.ToString());
            }

C#で関数を追加する

NeoLuaではLuaでfunctionを書く方法だけでなくC#で関数を追加することもできる。NeoLuaではLua標準ライブラリの「os名前空間」が未実装だったりするので、日付・時間などを扱おうと思う場合は、この方法で実装すれば綺麗に決まる。Lua側からclr名前空間を叩いて実装する方法もあるがあんまり綺麗じゃない。

            using (var lua = new Lua())
            {
                var env = lua.CreateEnvironment();

                // C#で書かれたadd関数を追加
                env.Add("add", new Func<int,int,int>((a,b) => a+b));

                // Lua側から呼び出してみる
                var ret = env.DoChunk(@"return add(1,2)", "main.lua");
                Console.WriteLine(ret);
            }

ちなみにdynamic版の場合だと更に簡潔明瞭。

            using (var lua = new Lua())
            {
                var env = lua.CreateEnvironment();

                // C#で書かれたadd関数を追加
                env.add = new Func<int,int,int>((a,b) => a+b);
            }

C#でクラスを追加する

前述のC#で関数を追加する方法と同じ要領でクラスも追加できる。

    class MainClass
    {
        public static void Main(string[] args)
        {
            using (var lua = new Lua())
            {
                var env = lua.CreateEnvironment();

                // C#で書かれたfooオブジェクトを追加
                env.Add("foo", new Foo());

                // Lua側から呼び出してみる
                var ret = env.DoChunk(@"return foo:ticks()", "main.lua");
                Console.WriteLine(ret);
            }
        }
    }

    class Foo 
    {
        public long ticks() 
        {
            return DateTime.Now.Ticks;
        }
    }

外部リンク

参考文献