Electronics, programming, VHDL, C++

Embedding Python in C#

Disclaimer: I don’t know C#. Take any line of code you see below with a grain of salt.

I have developed a USB based device. Now I have to provide a driver for it to the client (actually another developer team). Device is actually based on USB UART but we have a slightly complex protocol running over it, so I had to develop a library for interfacing. I did create one in Python. It wasn’t terribly hard, thanks to an awesome python library. But the client team work in C#. I couldn’t find a similar library for C#, and we are short on time. I know idea of embedding a binary parser/serializer written in Python into a C# library sounds awful but this is a prototype anyway so…

This is my story of embedding Python into a C# application, using Mono. I got confirmation from a friend that this also works on Visual Studio based projects.

First thing first, we are not embedding the regular Python implementation called CPython into C#. Instead we will use another Python implementation called IronPython. This python implementation is identical to the original one from a language perspective. But its designed to be integrated into the .NET platform. It can make use of .net libraries but there are also disadvantages. For example you can’t use a python library if it makes use of C libraries. Also there is only 2.7 version. If your python code makes use of Python 3 only modules or modules that have C library dependencies you better start looking alternatives to them.

Everything you need is included in the IronPython release package. Download it from here: http://ironpython.net/download/ and extract/install to your preferred location.

Create a new C# project. For this example I’m creating a console based project. Now add IronPython DLLs to your project. You can find these in the IronPython installation folder.

IronPython.dll

Microsoft.Scripting.dll

You will also need to add Microsoft.CSharp DLL to you project as well. In MonoDevelop this can be done from “References” window, “All” tab. I’m guessing its similar in Visual Studio (maybe not even required).

This should be fairly simple to understand. Using Python.CreateEngine we are creating an instance of Python interpreter to run our code. And using Execute() method we are running a piece of python code and assigning its result into a C# variable.

Now lets do something a little more useful. We will run a script, and access variables from inside this script. For this we will need to use a ScriptScope.

Now lets import some python modules in our script. You will see that any module other than sys cannot be imported in python. That’s because IronPython instance that we embedded inside our application doesn’t know where its standard libraries are. But they are right next to DLLs inside the directory named “Lib/” you will say.. Still, it doesn’t know about them. You have two options; either move those libraries into your applications running directory (not adviced), or let know IronPython where they are.

Important note: before running below example add IronPython.Modules.dll to your project as well.