6

I'm trying to get pythonnet to work in my .Net Core app running on Linux.

I've made a reference to Python.Runtime.dll (which I got from nuget) in my .Net Core project.

My code is:

using System;
using Python.Runtime;
namespace pythonnet_w
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Start");
            using (**Py.GIL()**) {
            //     blabla
            }
            Console.WriteLine("End");
        }
    }
}

I get this runtime error:

 Unhandled Exception: System.MissingMethodException: Method not found:     'System.Reflection.Emit.AssemblyBuilder      
 System.AppDomain.DefineDynamicAssembly(System.Reflection.AssemblyName, System.Reflection.Emit.AssemblyBuilderAccess)'.
    at Python.Runtime.CodeGenerator..ctor()
    at Python.Runtime.DelegateManager..ctor()
    at Python.Runtime.PythonEngine.Initialize(IEnumerable`1 args, Boolean setSysArgv)
    at Python.Runtime.PythonEngine.Initialize(Boolean setSysArgv)
    at Python.Runtime.PythonEngine.Initialize()
    at Python.Runtime.Py.GIL()
    at pythonnet_w.Program.Main(String[] args) in D:\Development\~.Net libraries (3.part)\phytonnet\.Net Core test (phytonnet)\c#\pythonnet_test\Program.cs:line 10
 /usr/sbin/pythonnet_w: line 5: 19487 Aborted                 dotnet "/usr/share/pythonnet_wit/pythonnet_w.dll"

Tried to find a solution in these threads but without any luck:

How do I run a py file in C#?

Call Python from .NET

UPDATE:

I tried to open \pythonnet-master\src\runtime**Python.Runtime.csproj** in Visual Studio to see if I can compile it to .Net or .Core, but I can only compile to .Net framework. I found this article "How to port from .net framework to .net standard" Is that what I have to do?

MrCalvin
  • 1,675
  • 1
  • 19
  • 27

2 Answers2

6

I finally had success by using a self-compiled Python.Runtime.dll as of version 2.4.0. There are two options to create a working DLL:

  • Remove the other target framework net461 from the respective project file (leaving only netstandard2.0).
  • Run dotnet build using the appropriate options

For option 2, the following works(in Windows, Mac and Linux):

  1. Clone the pythonnet repo (https://github.com/pythonnet/pythonnet)
  2. In the pythonnet folder, cd src\runtime
  3. Run dotnet build -c ReleaseWinPY3 -f netstandard2.0 Python.Runtime.15.csproj in Windows(in Mac/Linux, replace ReleaseWinPY3 with ReleaseMonoPY3 because the former use python37 and the later use python3.7)
  4. Set DYLD_LIBRARY_PATH in Mac or LD_LIBRARY_PATH in linux(Windows skip):
export DYLD_LIBRARY_PATH=/Library/Frameworks/Python.framework/Versions/3.7/lib
  1. Use the built DLL bin\netstandard2.0\Python.Runtime.dll as DLL reference in your Visual Studio .NET Core project (mine targets netcoreapp2.2, netcoreapp3.1 is also tested ok), e.g. in conjunction with the following code,
using System;
using Python.Runtime;

namespace Python_CSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Py.GIL())
            {
                dynamic os = Py.Import("os");
                dynamic dir = os.listdir();
                Console.WriteLine(dir);

                foreach (var d in dir)
                {
                    Console.WriteLine(d);
                }
            }
        }
    }
}
liviaerxin
  • 579
  • 6
  • 13
MP24
  • 3,110
  • 21
  • 23
  • I had to use the configuration 'ReleaseMonoPY3' instead of 'ReleaseWinPY3' to get it to work, otherwise it tried to load python37 and kernel32 instead of libpython3.7m.so. Ubuntu16 + dotnet core – Marcus10110 Sep 13 '19 at 03:56
  • 1
    You, sir, deserve a cookie! – Nissim Nov 05 '19 at 21:32
  • I tried this, but I get the error: "An unhandled exception of type 'System.DllNotFoundException' occurred in Python.Runtime.dll: 'Unable to load shared library 'python38' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(libpython38, 1): image not found'" I've installed python 3.8.1 via pyenv (and homebrew) but I'm using the pyenv version by default by setting my path to that install... am I missing something here (On macos)... Is there a way I can hard code/copy a python library for this to use? – Mark McGookin Jan 06 '20 at 23:10
  • I had success when I put python.exe and DLLs into the same directory as the runtime DLL. Did not test with other paths, as I do not have a system-wide installation of Python. – MP24 Jan 07 '20 at 06:58
1

You can host the IronPython interpreter right in your .NET application. For example, using NuGet, you can download the right package and then embed the script execution (actually the IronPython engine) right into your application.

Ref: https://medium.com/better-programming/running-python-script-from-c-and-working-with-the-results-843e68d230e5

VISHMAY
  • 699
  • 5
  • 20
  • I started her(with ironpython) but found it is only compatible with python 2.xx. is this right? Seems to be an accepted fact in all my searches. – GarethReid Mar 08 '22 at 09:16
  • I have tried using IronPython. It has worked great for alot of functions. But I ran into issues (native exceptions) when calling functions from the pyserial library. I have since moved to pythonnet with no issue. Just a bit more complicated to get started with. Check the wiki's if you try it. – Exzile Feb 01 '23 at 03:43