CSharp DLL into python 3.5 how to the easy way


Why DLLs in python?

Recently I was faced with a very dirty problem. Imagine you have some interface written in C# and lets say it is a somewhat clean and complete class collection to control a fancy micro-fluidics pump. Now you have to automate a lot of stuff in python, in this case GUI automation of multiple different outsourced programs for research purposes. In those cases you often may choose some quick and unorthodox way to save time. Because yes the end product shall be a proof of concept and nothing more… The perfect setting!

So what do you do? Threaded com-port interfaces are not exactly “built into” python and rewriting 2k lines of code can be life threatening if the needed libraries are… less then ideal.

Well we all still love python so there is that! Perfect lets build a DLL and expose the important functions to python!

Party time:

First we create a project by choosing the class library:

In our case we will keep it simple and write a simple function we want to expose! A Class file should be visible now. In case it is not don’t worry, just create a new cs file in the following path:

Solution Explorer >>Project >>Right-Click >>Add >>New Item... >>Class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;

namespace MyNameSpace
{
    public class MyClass
    {
        private static String hellostring = "Hello from Mrs. C";
        [DllExport("hello", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static string hello(String andstring)
        {
            return hellostring + " and " + andstring;
        }
    }
}

Now you may have noticed “DllExport” is kind of unknown. Let us handle this by using the NuGet Package Manager:

Tools >>NuGet Package Manager >>Manage NuGet Packages for Solution... >>[Browse].

Now search for UnmanagedExports mark your project and choose install. This package takes care of the exposition of the entry points in your DLL. This will make life easier for us since we don’t actually need to worry about entry points that much. Now you should be able to add our using-directive to the code:

using RGiesecke.DllExport;

What is important to prevent Errors:

  • Your exposed functions must be “static”!
  • If you get the Error that “ilsdam” is not found: uninstall the NuGet Package we installed start Visual Studio in Admin mode and reinstall the package. >>source
  • Set a specific build architecture! Don’t let Visual Studio be in the “Any CPU” mode which is the default in compilation! >>source

Now you should be able to just compile in “Release” mode. Ignore the obvious Error Msg Box which tells you that you wont see anything going on the screen…

In python

So now you are ready to copy the DLL into your site-packages folder of your python install or you have to point python directly to your dll as shown below:

import clr
clr.AddReference(R'C:\Path to the dll\cdp.dll')  # The R lets python interpret the string RAW so you can put in Windows paths easy
from MyNameSpace import MyClass
my_instance = MyClass()
x = my_instance.hello("Mr. Sharp")
print(x)  # Output: Hello from Mrs. C and Mr. Sharp

Done! You should see the output produced from the python script.

Further reading:

http://www.codeguru.com/csharp/csharp/cs_misc/dllsandexecutables/article.php/c4239/Creating-and-Using-C-DLLs.htm

https://stackoverflow.com/questions/2077870/how-to-load-a-c-sharp-dll-in-python

Full Code:

cbp.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;

namespace MyNameSpace
{
    public class MyClass
    {
        private static String hellostring = "Hello from Mrs. C";
        [DllExport("hello", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static string hello(String andstring)
        {
            return hellostring + " and " + andstring;
        }
    }
}

python:

import clr
clr.AddReference(R'C:\Path to the dll\cdp.dll')  # The R lets python interpret the string RAW so you can put in Windows paths easy
from MyNameSpace import MyClass
my_instance = MyClass()
x = my_instance.hello("Mr. Sharp")
print(x)  # Output: Hello from Mrs. C and Mr. Sharp

Leave a comment

Your email address will not be published. Required fields are marked *