I'm having trouble getting PythonNet to work with a C# dll which references SixLabors.ImageSharp (v3.1.3). My bare minimal C# code (.NET 7.0 class library, which is compiled into a dll) is shown below. It contains three test methods, RunTest1, RunTest2, and RunTest3.
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
namespace PythonNetTest
{
public class TestClass
{
public void RunTest1()
{
Console.WriteLine("Test PythonNet");
}
public Image RunTest2()
{
return null;
}
public Image RunTest3()
{
return new Image<Rgba32>(100, 100);
}
}
}
The Python code which I'm using to load and work with this C# dll is below:
import os
import sys
import clr
from System.Reflection import Assembly
from System.IO import File
from System import Activator
clr.AddReference(r'<Path to ImageSharp DLL>\SixLabors.ImageSharp.dll')
path = r'<Path to C# dll>\PythonNetTest.dll'
dll = Assembly.Load(File.ReadAllBytes(path))
obj_type = dll.GetType('PythonNetTest.TestClass')
obj = Activator.CreateInstance(obj_type)
obj.RunTest1()
v2=obj.RunTest2()
v3=obj.RunTest3()
When I run the Python code, RunTest1 correctly prints the string "Test PythonNet", and RunTest2 correctly returns a null object.
RunTest3, however, fails with the following exception in the Python console:
TypeLoadException: Could not load type 'System.Environment' from assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
at SixLabors.ImageSharp.Configuration..ctor(IImageFormatConfigurationModule[] configurationModules)
at SixLabors.ImageSharp.Configuration.CreateDefaultInstance()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at SixLabors.ImageSharp.Configuration..cctor()
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ~\miniconda3\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
exec(code, globals, locals)
File c:\users\<***>\documents\untitled0.py:31
v3=obj.RunTest3()
TypeInitializationException: The type initializer for 'SixLabors.ImageSharp.Configuration' threw an exception. ---> System.TypeLoadException: Could not load type 'System.Environment' from assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
at SixLabors.ImageSharp.Configuration..ctor(IImageFormatConfigurationModule[] configurationModules)
at SixLabors.ImageSharp.Configuration.CreateDefaultInstance()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at SixLabors.ImageSharp.Configuration..cctor()
--- End of inner exception stack trace ---
at SixLabors.ImageSharp.Image`1..ctor(Int32 width, Int32 height)
at PythonNetTest.TestClass.RunTest3()
What could be the cause of this exception? I'm using the ImageSharp dll, which I downloaded directly. I'm not using the ImageSharp source code to build the ImageSharp dll. However, I did take a look at the ImageSharp source code, and it seems it uses some Environment functions, such as Environment.ProcessorCount and Environment.Newline. I presume these come from System.Runtime.
Any help is appreciated.
I figured it out on my own. I'm posting the answer, in case it helps somebody else.
I had to modify my Python code as follows:
from pythonnet import load
load('coreclr')
import os
import sys
import clr
from System.Reflection import Assembly
from System.IO import File
from System import Activator
clr.AddReference(r'<Path to ImageSharp DLL>\SixLabors.ImageSharp.dll')
path = r'<Path to C# dll>\PythonNetTest.dll'
dll = Assembly.Load(File.ReadAllBytes(path))
obj_type = dll.GetType('PythonNetTest.TestClass')
obj = Activator.CreateInstance(obj_type)
obj.RunTest1()
v2=obj.RunTest2()
v3=obj.RunTest3()
Basically, explicitly load 'coreclr'. Hope this is of use to others.