当前位置:   article > 正文

VS2013使用pythonnet在C#中调用python的.pyd文件_c# 在虚拟环境调用pythonnet

c# 在虚拟环境调用pythonnet

VS2013使用pythonnet在C#中调用.pyd文件

  简单记录一下,如何借助pythonnet在VS2013中使用C#调用python函数

1、环境配置

  1、VS2013,框架.Net Framwork 4.5
  2、pythonnet_py37_win
  3、anaconda管理的python3.7虚拟环境及相关库

2、VS2013安装pythonnet

注意:
  在VS2013中的NnGet管理器中直接搜索pythonnet是找不到的(可能是VS2013的NuGet管理器版本的问题),显示如下图。在这里插入图片描述
  所以我在VS2013中使用pythonnet时选择在VS2019中下载pythonnet_py37_win,之后加载到VS2013中使用。
puthonnet加载方式:
  1、VS2019中随意建一个C#工程,打开NuGet包管理器
在这里插入图片描述
  2、在NuGet解决方案中查找pythonnet,然后选择对应python版本的pythonnet(由于之后要使用.Net Framwork所以不选择standard)。要记得右上角的程序包源切换到nuget.org,不然找不到包。
在这里插入图片描述
  3、将需要pythonnet版本安装到当前项目中,此时在项目文件夹中会生成一个packages文件夹,内部包含着pythonnet的NuGet包。
  4、进入VS2013项目下,右键引用->管理NuGet程序包,将这个packages文件路径添加上,然后将此路径下pythonne_py37_win安装到当前项目中即可。
在这里插入图片描述
  5、安装成功后,应用中会出现Python.Runtime

3、.pyd文件的生成

  在这里的就不解释.pyd文件是什么了,类比一下可以简单理解为python中的dll文件。这里简单生成一个.pyd文件,可以点击参考这里
  下面定义一个简单的python函数

# MainModule.py
def ShowNum():
	return 9999
  • 1
  • 2
  • 3

  将这个文件导出为一个.pyd文件

# Setup.py
import Cython.Build
import distutils.core

def py2c(file):
    cpy = Cython.Build.cythonize(file, language_level=3)  # 返回distutils.extension.Extension对象列表

    distutils.core.setup(
        name='pyd的编译',          # 包名称
        version="1.0",            # 包版本号
        ext_modules=cpy           # 扩展模块
    )

if __name__ == '__main__':
    file = "MainModule.py"
    py2c(file)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

  之后在命令行中执行python Setup.py build_ext --inplace,来生成.pyd文件。
注意:
1、若使用了虚拟环境,执行此命令时需要切换到对应虚拟环境下;
2、生成.pyd文件包含python版本信息,比如MainModule.cp37-win_amd64.pyd,其中.cp37-win_amd64可以省略。

4、C#调用.pyd文件

文件准备:
  1、C#项目切换到x64
  2、将.pyd文件,python37.dll放入到项目的bin->x64->debug文件夹中

调用:

  首先,需要应用Python.Runtime命名空间

using Python.Runtime;
  • 1

  之后,由于使用了虚拟环境需要添加虚拟环境路径,这一部分也可以参考pythonnet官方的实例

string pathToVirtualEnv = @"D:\Anaconda3\envs\w2";
            Environment.SetEnvironmentVariable("PATH", pathToVirtualEnv, EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("PYTHONPATH", pathToVirtualEnv + "\\Lib\\site-packages;" + pathToVirtualEnv + "\\Lib", EnvironmentVariableTarget.Process);

            PythonEngine.PythonHome = pathToVirtualEnv;
            PythonEngine.PythonPath = PythonEngine.PythonPath + ";" + Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  最后,.pyd文件的调用可以参考的官方示例调用,下面给出一个完整的调用示例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using Python.Runtime;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            string pathToVirtualEnv = @"D:\Anaconda3\envs\w2";
            Environment.SetEnvironmentVariable("PATH", pathToVirtualEnv, EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("PYTHONPATH", pathToVirtualEnv + "\\Lib\\site-packages;" + pathToVirtualEnv + "\\Lib", EnvironmentVariableTarget.Process);

            PythonEngine.PythonHome = pathToVirtualEnv;
            PythonEngine.PythonPath = PythonEngine.PythonPath + ";" + Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);

            using (Py.GIL())
            {
                dynamic np = Py.Import("MainModule");
                int i = np.PYDTest();
                Console.WriteLine(i);

                Console.ReadLine();
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述
注意:
  VS2013中,无法直接在控制台显示Python中print()函数的打印内容(VS2019可以),测试过程中需要将测试内容作为返回值接收并在控制台打印。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/478458
推荐阅读
相关标签
  

闽ICP备14008679号