IronPythonのホスティング
IronPython側から.NETのクラスライブラリを呼び出す例は見ましたので、C#からIronPythonを使ってみます。
以前、IronPythonスクリプトを実行するだけの例は記事にしているので、今回は実行結果を受け取ったり、IronPythonオブジェクトを操作してみます。
まずは、今回のテストに使うIronPythonのソースコード。
class Calc: def add (self, x, y): return x + y def subtract (self, x, y): return x - y g = globals () calc = Calc() # C#から呼ばれるときは、以下の変数が設定されている if 'cs_arg1' in g and 'cs_arg2' in g: retval = calc.add (cs_arg1, cs_arg2) else: print calc.add (10, 20)
calc.pyと名前を付けて保存します。見ての通り、足し算、引き算を行う単純ならクラスです。
ソースのこの部分に注意してください。
# C#から呼ばれるときは、以下の変数が設定されている if 'cs_arg1' in g and 'cs_arg2' in g:
cs_arg1、cs_arg2が存在するかどうか処理を分けています。これらの変数はC#側から設定します。
次に、IronPythonをホスティングするC#側のソースコードです。
using System; using IronPython.Hosting; using IronPython.Runtime; public class Program { public static void Main () { PythonEngine engine = new PythonEngine (); // IronPython側に以下の変数を用意する engine.SetVariable ("cs_arg1", 1); engine.SetVariable ("cs_arg2", 2); // スクリプトの実行 engine.ExecuteFile ("calc.py"); // Python上の変数を取得 object o = engine.GetVariable ("retval"); Console.WriteLine ("1 + 2 = {0}", o); // calc変数(Calcクラスのインスタンス)を取得 OldInstance self = engine.GetVariable ("calc") as OldInstance; // Calcクラスを取得 OldClass calc = self.__class__ as OldClass; // subtractメソッドを取得 Function3 func3 = calc.__dict__["subtract"] as Function3; // 呼び出し Console.WriteLine ("1 - 2 = {0}", func3.Call (self, 1, 2)); } } /* 結果 1 + 2 = 3 1 - 2 = -1 */
これもhost.csと名前を付けて保存します。で、コンパイル。
$ csc /r:IronPython.dll host.cs
host.exeを実行すると足し算、引き算が行われますね。
足し算側は単純な例で、C#から引数を渡してIronPython側で計算し、結果のみを取得します。一方、引き算側はcalcオブジェクトを取得してコントロールしています。リフレクション経由にイメージは近いですね。IronPythonのオブジェクトは.NETの型と違い、Hashtableの固まりみたいなものなので、このように使うことになります。