2

I try to use an assembly for .NET framework 4.8 via Pythonnet. I am using version 3.0.1 with Python 3.10. The documentation of Pythonnet is stating:

You must set Runtime.PythonDLL property or PYTHONNET_PYDLL environment variable starting with version 3.0, otherwise you will receive BadPythonDllException (internal, derived from MissingMethodException) upon calling Initialize. Typical values are python38.dll (Windows), libpython3.8.dylib (Mac), libpython3.8.so (most other Unix-like operating systems).

However, the documentation unfortunately is not stating how the property is set and I do not understand how to do this.

When I try:

import clr
from pythonnet import load

load('netfx')

clr.AddReference(r'path\to\my.dll')

unsurprisingly the following error is coming up

Failed to initialize pythonnet: System.InvalidOperationException: This property must be set before runtime is initialized
   bei Python.Runtime.Runtime.set_PythonDLL(String value)
   bei Python.Runtime.Loader.Initialize(IntPtr data, Int32 size)
   bei Python.Runtime.Runtime.set_PythonDLL(String value)
   bei Python.Runtime.Loader.Initialize(IntPtr data, Int32 size)
[...]
in load
    raise RuntimeError("Failed to initialize Python.Runtime.dll")
RuntimeError: Failed to initialize Python.Runtime.dll

The question now is, where and how the Runtime.PythonDLL property or PYTHONNET_PYDLL environment variable is set

Thanks, Jens

JMP
  • 123
  • 6

2 Answers2

0

I believe this is because import clr internally calls pythonnet.load, and in the version of pythonnet you are using this situation does not print any warning.

E.g. the right way is to call load before you call import clr for the first time.

LOST
  • 2,956
  • 3
  • 25
  • 40
  • if i do: from pythonnet import load load('netfx') import clr clr.AddReference(r'path\to\my.dll') I get the following error: System.BadImageFormatException In the meanwhile however I managed to access the dll via ctypes. But would be interesting what I am doing wrong here anyway. – JMP Feb 07 '23 at 09:17
  • `BadImageFormatException` usually means your DLL bitness does not match the bitness of your process. – LOST Feb 07 '23 at 20:55
0

The way I understand your use case is for Embedding .NET in Python however, the way I understand the requirement to "set Runtime.PythonDLL property" is that is for Embedding Python in .NET which was my use case. Anyhow, maybe the following will be useful.

Hidden at the bottom of the main GitHub README.md is a link to the WiKi (and of course the tab at the top of the GitHub repo) where thankfully there is a lot more detailed information and links to useful articles.

The main README.md asserts Runtime.PythonDLL "must be set" yet their example code does not illustrate doing so. Furthermore, the documentation on the official website asserts Python.Runtime.dll must be "referenced" which further confuses things.

In my experience Python.Runtime.dll was automatically referenced when installing the pythonnet NuGet package via Visual Studio. Perhaps Python.Runtime.dll does not automatically get referenced in earlier version or maybe when Python.NET is installed in other ways other than by using NuGet?

To answer your question "how to set Runtime.PythonDLL property?". My understanding is the way that is done is by assigning a string path to that property before the other usual setup:

Runtime.PythonDLL = @"C:\Users\<username>\AppData\Local\Programs\Python\Python310\python38.dll"

In my case, I found this path by using where python on Windows (which in bash, or Get-Command in PowerShell):

C:\>where python
C:\Users\<username>\AppData\Local\Programs\Python\Python310\python.exe