I learned that I can run Python from .Net with this article and used Pythonnet I tried to see it. I was addicted to haste, so I will write it down as a memorandum.
The environment used for development, the Python version, and Pythonnet are as follows.
First, download the complete source code from Pythonnet. Extract and open the folder containing pythonnet.sln.
Open the solution file pythonnet.sln.
The target OS, Python version, etc. can be determined from the project structure. --Release WinPy3 (Windows version of Python 3 series release version) --DebugMono (Mono version of Python2 debug version) It can be specified in the form of.
By playing with this, the definition value of the "conditional compilation symbol" of the project is rewritten, and the condition by # if
in the source is switched.
If you look at the source code runtime.cs
, you can see that it is switched as follows.
#if PYTHON34
const string _minor = "4";
#elif PYTHON35
const string _minor = "5";
#elif PYTHON36
const string _minor = "6";
#elif PYTHON37
const string _minor = "7";
#elif PYTHON38
const string _minor = "8";
#else
#error You must define one of PYTHON34 to PYTHON38
#endif
#if WINDOWS
internal const string dllBase = "python3" + _minor;
#else
internal const string dllBase = "python3." + _minor;
#endif
With this, you are switching the difference in the name of Python DLL depending on the OS.
In this environment, it is Python3.8 on Windows, so build it with the configuration of ReleaseWinPY3.
Since Python3.8 is used, let's modify the contents of "conditional compilation symbol" in the "build" item of the property of Python.Runtime as PYTHON3; PYTHON38; UCS2
.
The platform of Python.Runtime can only be selected from Any CPU, so leave it as it is.
When you build it, you will have bin \ Python.Runtime.dll
, so copy it to any location you like.
Now that the Pythonnet library is ready, let's create a simple Hallo world app. Let's make it by referring to the sample in this article.
In the above article, it is written in C #, but this is written in VB.Net.
First, in Visual Studio, select "Console App (.NET Framework)" from "Create New Project" to create a project. Here, .NET Framework 4.7.2 is specified as the framework.
Then, select "References" from the project properties so that you can refer to Python.Runtime.dll, and specify the location where you put Python.Runtime.dll
in" Add ".
Now you are ready to go.
After that, create the following sample code.
Imports Python.Runtime
Imports System
Imports System.IO
Imports System.Linq
Class TestPython
Public Sub AddEnvPath(paths As String())
Dim envPaths As IList(Of String) = Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator.ToString).ToList
For Each path In paths
If path.Length > 0 And Not envPaths.Contains(path) Then
envPaths.Insert(0, path)
End If
Next
Environment.SetEnvironmentVariable("PATH", String.Join(Path.PathSeparator.ToString, envPaths), EnvironmentVariableTarget.Process)
End Sub
End Class
Module Module1
Sub Main()
Dim test_python = New TestPython
Dim PYTHON_HOME = "C:\Users\xxx\anaconda3\envs\Python38"
vms_python.AddEnvPath({PYTHON_HOME,
Path.Combine(PYTHON_HOME, "Library\bin")})
PythonEngine.PythonHome = PYTHON_HOME
Dim python_paths() As String = {PythonEngine.PythonPath, Path.Combine(PYTHON_HOME, "Lib\site-packages"), Path.Combine("C:\tmp")}
PythonEngine.PythonPath = String.Join(Path.PathSeparator.ToString, python_paths)
PythonEngine.Initialize()
Using Py.GIL()
PythonEngine.RunSimpleString("import sys")
PythonEngine.RunSimpleString("print(""Hallo World"")")
End Using
End Sub
End Module
As for the content,
--Create a helper class TestPython
that adds the path to the environment variable PATH
--Enter the Anaconda path in PYTHON_HOME
--Add PYTHON_HOME
and PYTHON_HOME \ Library \ bin
to the environment variable PATH
After making the preparation, for Python.Runtime
,
--Tell me where Python is with PythonEngine.PythonHome = PYTHON_HOME
--Teach PythonEngine.PythonPath
the search path for Python
--Initialize with PythonEngine.Initialize ()
After that
Using Py.GIL()
PythonEngine.RunSimpleString("import sys")
PythonEngine.RunSimpleString("print(""Hallo World"")")
End Using
It is a simple program that displays Hello World
with.
So let's run it.
Unhandled exception: System.DllNotFoundException: DLL 'python3.8'Cannot be read:The specified module cannot be found.(Exception from HRESULT:0x8007007E)
The error is that the DLL cannot be loaded.
For the time being, I will write only the cause and solution.
When I looked it up,
--I'm looking for python3.8.dll
instead of python38.dll
(named python38.dll
on Windows)
-- Dumpbin command shows that Python.Runtime.dll
is built as x86 </ del>
I found that the cause was two points </ del>.
(Fixed by commenting on 2020/08/04. It was okay that Python.Runtime.dll was built on AnyCPU. I intended to build the calling program on x64, but it was AnyCPU, so 32bit It seems that it was a call. It seems safe to delete AnyCPU of the calling program just in case)
Therefore, the solution is the following two points </ del>.
--Since the WINDOWS
symbol is not defined when building Pythonnet, I am looking for a DLL named python3.8.dll
, so the WINDOWS
symbol is added to the" conditional compilation symbol "in Python.Runtime. To add
- Set the target platform of Python.Runtime to x64
</ del>
When I refer to the DLL built in this way (it is necessary to exclude the old DLL and then refer to it again), the execution result was successfully obtained as shown below.
Hallo World
Somehow, I had a lot of trouble with Hallo World alone, so this article ends here. I would like to write the code that actually calls and uses Python in the next article.
Recommended Posts