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

4

3

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

Romanic answered 16/4, 2021 at 9:12 Comment(0)
H
1

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)
Huygens answered 19/4, 2021 at 23:34 Comment(0)
S
0

The full-stop between UVtools and Core prevents you from accessing the object of core which contains the About Method. You must find a way to have just one name with a dot or full-stop inbetween the class and method in the class. Also note that if you import a dll file through the assembly path. the entire library in that assembly path is accessible.

The example on GymSharp below is a good example of how to implement and use the pythonnet library and implementing an assembly import is given below:

#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)

ModuleNotFoundError: No module named 'UVtools'

Statistician answered 15/7, 2022 at 6:58 Comment(0)
C
0

I also had the ModuleNotFoundError. After switching to .NET Framework 4.8 everything worked. My initial project was with .NET Core 3.1 which worked for this question, but not for me. I also tried .NET 5.0, but that gave the same error.

I used:

  • pythonnet 2.5.2
  • Python 3.8.13
  • Class Library with .NET Framework 4.8
Centaurus answered 2/9, 2022 at 14:53 Comment(0)
N
0

I was having the same issue and I had to go back to my C# file and sort out the namespace.

In your about.cs file, the namespace is set to UVtools.Core, but in Python it's trying to import from namespace UVtools/Core because the dot is making it seem as though 'UVtools' by itself is a different folder. Try renaming the project files from 'UVtools.Core' to 'UVtools' and in the about.cs file change:

namespace UVtools.Core;

to

namespace UVtools;

then re-build the assembly. And in Python, try:

from UVtools import About

This might do the trick.

Nibbs answered 25/3 at 5:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.