Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"No module named" error when attempting to importing c# dll using Python.NET

I'm attempting to import a c# module into Python using python.NET under Anaconda

This has been installed using pip install pythonnet which reported "Successfully installed pythonnet-2.5.2"

From there with python it should be possible to do something like the following which isn't working properly. Jetbrains dotPeek can see the module, and calls to standards Windows dlls work fine. What am I doing wrong?

clr.AddReference(R'C:\Program Files (x86)\UVtools\UVtools.Core.dll')
from UVtools.Core import About
>>ModuleNotFoundError: No module named 'UVtools'
# never gets here:
print(About.Software)

This works fine:

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form
form = Form()
print(dir(form))
>> ['AcceptButton', ...

This also doesn't work (trying to access the same dll in a different way)

import System
uvTools = System.Reflection.Assembly.LoadFile(R'C:\Program Files (x86)\UVtools\UVtools.Core.dll')
print(uvTools.FullName)
print(uvTools.Location)
>>UVtools.Core, Version=2.8.4.0, Culture=neutral, PublicKeyToken=null
>>C:\Program Files (x86)\UVtools\UVtools.Core.dll
# But the following all fail with the same fundamental error:
print(uvTools.UVtools.Core.About)
print(uvTools.Core.About)
print(uvTools.About)
>>AttributeError: 'RuntimeAssembly' object has no attribute 'About'

JetBrains dotPeek can see the modules, which to me would have implied it's not an issue with the dll.

enter image description here

I did see elsewhere that if trying to use ctype then you need to include "[DllExport("add", CallingConvention = CallingConvention.Cdecl)]" in the c# basecode, but I don't think this applies to python.NET clr calls

like image 497
David Avatar asked Dec 31 '25 11:12

David


1 Answers

I believe your issue is that you are using the file extension in the import statement.

This is what works for me:

#add the directory the assembly is located in to sys.path.
assembly_path1 = r"C:\DesktopGym\src\MouseSimulatorGui\bin\Debug"
import sys
sys.path.append(assembly_path1)

import clr
#add a reference to the assembly, by name without the .dll extension.
clr.AddReference("GymSharp")

#import the class. Here this is a public class, not static.
from GymSharp import TicTacToeSharpEnvironment

# instantiate a new instance
env = TicTacToeSharpEnvironment()

# call a method
result = env.HelloWorld()

print (result)

In C#, GymSharp is the name space and TicTacToeSharpEnvironment is the name of the public class:

namespace GymSharp
{
    public class TicTacToeSharpEnvironment
    {
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

I also tested my a Static class with a static method, so that is not the issue.

namespace GymSharp
{

    public static class StaticFoo
    {
        public static string StaticHelloWorld => "Static hello World";
    }

From Python

from GymSharp import StaticFoo
print (StaticFoo.StaticHelloWorld)
like image 131
Alexander Higgins Avatar answered Jan 06 '26 12:01

Alexander Higgins



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!