[IronPython] IP 2.0 Alpha 7 embedding
Slide
slide.o.mix at gmail.com
Fri Dec 21 22:39:59 CET 2007
I have come up with an example (very simple) of embedding IP 2.0 into
a C# app and doing back and forth handling of objects (objects
declared in Python and object declared in C#). I am interested to know
if I am doing some things the best way as I've just been going kind of
hit and miss. Can someone do a little critiquing of this code and see
if I am being dumb? The windows app has two RichTextBoxes on it (one
for input, the other for output), a clear button and a "go" button.
When the "go" button is pressed, it writes the source out to a temp
file and then creates the object instance from the script. Thanks!
Here is the code:
test.py
============================================
import TestLib, unittest
def Print(message):
output.AppendText("%s\r\n" % message)
class Test(TestLib.ITest):
def Print(self, message):
output.AppendText("%s\r\n" % message)
Print("Hello, world!")
ITestLib.cs located in TestLib.dll
==========================================
using System;
using System.Collections.Generic;
using System.Text;
namespace TestLib
{
public interface ITest
{
void Print(string message);
}
}
MainForm.cs located in IPEmbed.exe which references TestLib.dll
============================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython.Runtime;
using IronPython.Hosting;
namespace IPEmbed
{
public partial class Form1 : Form
{
private ScriptScope __main__;
private LanguageContext _context;
public Form1()
{
InitializeComponent();
_context = LanguageContext.FromEngine(PythonEngine.CurrentEngine);
_context.SetScriptSourceSearchPaths(new string[] {
Environment.CurrentDirectory,
Path.Combine(Environment.CurrentDirectory, "Lib") });
}
// sets up the script engine, etc
private void go_Click(object sender, EventArgs e)
{
ScriptDomainManager.CurrentManager.Host.DefaultModule.ClearVariables();
if (input.Text.Length == 0)
return;
string filepath = Path.GetTempFileName();
File.WriteAllText(filepath, input.Text);
__main__ =
ScriptDomainManager.CurrentManager.CompileModule("__main__",
SourceUnit.CreateFileUnit(_context, filepath));
ScriptDomainManager.CurrentManager.PublishModule(__main__,
"__main__");
Microsoft.Scripting.ClrModule.GetInstance().AddReference("TestLib");
__main__.SetVariable("output", output);
__main__.Execute();
TestLib.ITest test = CreateInstanceFromInterface<TestLib.ITest>();
if (test != null)
test.Print("Hello, world!");
}
// this method will find a class in the python code that
implements a given interface and create and instance
// of that class, returning it as the interface
private T CreateInstanceFromInterface<T>()
{
T result = default(T);
IAttributesCollection attrs =
IronPython.Runtime.Types.PythonModuleOps.Get__dict__(__main__);
foreach (KeyValuePair<object, object> attr in attrs)
{
IronPython.Runtime.Types.PythonType attr_type =
attr.Value as IronPython.Runtime.Types.PythonType;
if (attr_type != null)
{
foreach (IronPython.Runtime.Types.PythonType dt in
attr_type.BaseTypes)
{
if (dt.UnderlyingSystemType != null &&
dt.UnderlyingSystemType == typeof(T))
{
CodeContext context = new
CodeContext(__main__.Scope, _context, new ModuleContext(__main__));
result = (T)attr_type.CreateInstance(context);
break;
}
}
}
}
return result;
}
private void clear_Click(object sender, EventArgs e)
{
output.Clear();
}
}
}
More information about the Ironpython-users
mailing list