How to use C# Class Libraries (dll) in Python

Hi,

I am asking myself if I can spare the effort of re-writing all C#-modules I created in C# in Class-Libraries and might use them in Python.
I am aware that somthing like that is happening in RhinoCommon, but I am way to unexperienced to understand if this works with any dlls?

I found this topic for the same issue with C++, but I am a bit lost in there.

Does this question make any sense at all or is it hard to achieve?

Thanks,
T.

it is not clear to me what you mean by saying “C#-modules” – does this mean something like C# code you have written in grasshopper?

either way, you can compile your C# code into a .NET class library, and reference it from python in rhino by using:

import sys
import clr
sys.path.append('C:/path/to/my/libraries')
clr.AddReference('my_library')

I do it this way because in my case, my .NET library wraps a native C dll that sits next to it, so adding the directory to the sys.path allows both to be found correctly

as for wrapping a native C or C++ library for use in C#, that is a wide topic, so you should probably try to get a regular C# library working first

1 Like

Hi @jdhill,
thanks for the input.

Sorry if I was a bit inspecific, let me correct that.

I have been writing a lot of C#-classes (Class Libaries compiled to dlls) for my Rhino Plugin. This means they are compiled in some folders. Fine. :slight_smile:
For some cases, when working on projects and we switch to Python, I have been starting to write the same stuff in Python - quite tedious and an effort to maintain. So it would be quite a thing for me not having to rewrite it, but using the existing code for Python.

either way, you can compile your C# code into a .NET class library, and reference it from python in rhino by using:

import sys
import clr
sys.path.append('C:/path/to/my/libraries')
clr.AddReference('my_library')

So as I understand it, this would be the solution, right?
As you say I can use the complied dll and

as for wrapping a native C or C++ library for use in C#, that is a wide topic, so you should probably try to get a regular C# library working first

I think my code should fulfill the requirements.

I gave it a try, but now I am not sure how I am able to call the modules.
Let’s say my dll is called TOOLBOX.dll, would I then say
import TOOLBOX?
If I do so it says:
name 'TOOLBOX' is not defined

Thanks,
T.

well first, just make sure the AddReference is working fine, by putting just a print('ok') or such after it

once that is working fine, then you just have to get the namespaces correct, which I cannot guess without knowing your code, but you might try something like from TOOLBOX import * and try to use some object from your C# code

Hi @tobias.stoltmann ,
In addition to Jdhill’s reply, you need to import the namespace from your .dll not the .dll name.
For example if your TOOLBOX.dll has the following structure:

TOOLBOX.dll
   RhinoTools - namespace
       Math - class
           Addition - static method
           Subraction - static method
       
       Geometry - class
           Square
           Hexagon

You would call the methods with:

import sys
import clr
sys.path.append('C:/path/to/my/libraries')
clr.AddReference('TOOLBOX')

import RhinoTools

add = RhinoTools.Math.Addition(1,2)
4 Likes

@djordje and @jdhill
Thanks for the aide so far!
Will check this tomorrow and keep you posted!

So with the dll attrached I tried this:
RhinoTools.zip (1.8 KB)

import sys
import clr

sys.path.append('C:\Temp')
clr.AddReference('RhinoTools')

import RhinoToolsGeometry
print(RhinoTools.RhinoToolsGeometry.TestMethod("NameA", "NameB"))

Which leads me to the following error:

Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Traceback:
  line 4, in <module>, "C:\Users\TSTOLT~1\AppData\Local\Temp\TempScript.py"

You might want to reference the .dll more explicitly:

This also helps tremendously to avoid dependency hell.

Hi @AndersDeleuran,
thanks for the hint.

It still throws

Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Traceback:
  line 5, in <module>, "C:\Users\TSTOLT~1\AppData\Local\Temp\TempScript.py"

So I guess there is something wrong with my dll?

Hi @tobias.stoltmann ,
RhinoToolsGeometry is a class. You should import the RhinoTools namespace:

import sys
import clr

sys.path.append('C:\Temp')
clr.AddReference('RhinoTools')

import RhinoTools

rhGeo = RhinoTools.RhinoToolsGeometry()
test = rhGeo.TestMethod('NameA', 'NameB')
print ('test: ', test)

@djordje you right - of course!
But still I get the error:


Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

Hi @tobias.stoltmann ,
And you have RhinoTools.dll file inside C:\Temp folder? Strange.

Can you check if RhinoTools.dll file is blocked (right click on it, ‘Properties’ then choose ‘Unblock’ button, if it exists).

1 Like

You’re probably need to make the path here a raw string or use two backslashes:

That is:

sys.path.append(r'C:\Temp')

Or:

sys.path.append('C:\\Temp')

But at this point you also maybe want to upload the .dll (or an example file that also fails to reference ) so we can try to reference it ourselves. And again I’d suggest using the more explicit clr.AddReferenceToFileAndPath method.

Edit: Apologies, just saw that you already did upload the .dll. My bad. FWIW I can reference the .dll:

But cannot import the RhinoTools namespace:

2 Likes

@AndersDeleuran here I uploaded a sample dll.

Cheers. I just tried unblocking your .dll, placed it in the same folder as the KangarooSolver.dll and then inspected both. And there does appear to be an issue with the RhinoTools.dll:


1 Like

Thanks for checking this .
Then it must be an issue with the references right?

I suspect that both the referencing method you are using (i.e. not the clr.AddReferenceToFileAndPath method with a raw string, which works for me as demonstrated above) and the assembly/.dll itself might be a fault. If we compare to the KangarooSolver.dll again, we can see that RhinoTools.dll has no types to import (i.e. where the former has KangarooSolver and KPlankton):

1 Like

On my PC your dll file works without issues on Rhino 6. I just had to unblock it, that’s all:

So maybe the issue is that when you compiled your dll file, you chose a certain NET framework, which your Rhino 7 version does not support?

1 Like

Hi,


first of all I do not have an option to unblock the file.
Should I be worried?

What I used when creating the class library was this:
image

Rhino targets .Net 4.8 as I can see here:

From my class library I see that it is .Net 6, which then would explain it not working.
When I try to create a new one, I see that the possibilities are quite unsuitalbe, right?
image
My question now would be:
How do I first of all create the right project?

Hi @tobias.stoltmann ,
If it is not blocked, then it is okay. You shouldn’t be worried.
Class Library is also correct.
I would try to create a new Project in Visual Studio, just with the difference of: choosing some of the “NET Framework 4.X” For example 4.6.1 if you have it, as this seems to be the latest one I have installed.
Then copy-paste the C# code from your RhinoTools project, to this new one, and compile it.

1 Like