C#调用python程序内函数(二)python代码打包成库供C#调用

之前介绍了直接调用文件的方式 https://www.cnblogs.com/luosiqizi/p/16301501.html,适用比较简单的py代码,以下介绍将py代码打包成库的方式供C#调用

python:

新建一个py文件“__init__.py”,简单测试,加了两个简单方法,调用的时候可以测试,(PS:可以起名成别的,比如mm.py,这样在C#调用时就要在引入import处,在py库名后加上.mm  举例就像文中后半段C#部分的“dynamic ooo = Py.Import("mytest1.mm"));

def main():
    return 11111;

def test1(name):
    return name;

把它扔到一个文件夹 例如 “mytest1”下(这里只是测试一个py文件,实际生产用到的py代码和文件夹可以一股脑都扔到文件夹里),在mytest1外新建py文件“setup.py” ,内容:

from setuptools import find_packages,setup
setup(
    name = 'mytest1',
    version = '0.1',
    packages = find_packages(),
)

在setup.py路径内进入cmd, 运行 python setup.py install。 不报错的话直接就打包好了,可以在C#下import  mytest1,然后调用main或者test1方法。

以上只是我的简单测试方式,关于打包方式还有很多方式,比如先打包 python setup.py sdist  然后再安装 pip install xxx……。

 

C#:

根据本机的python版本选择引用的依赖包:

  如果是net6或者standard项目引用 pythonnet_netstaandard_py39_win(提示不支持net6就回退一个版本,vs的bug)

  如果是传统framework项目可以用standard类库转一手(但我试过有的电脑很顺利,有的电脑踩坑),也可以直接调引用pythonnet_py39_win

  这里要根据本机的python版本选择 37/38/39等,以及其他环境。

引用python的代码:

using (Py.GIL())//初始化Python引擎并获取解释器锁
{
    dynamic np = Py.Import("numpy");
    Console.WriteLine(np.cos(np.pi * 2));

    dynamic ooo = Py.Import("mytest1");
    dynamic s = "123";
    dynamic str = ooo.main();
    Console.WriteLine(str);
    str = ooo.test1(s);
    Console.WriteLine(str);
}

 就可以调用了,在调用自己python代码打包的库的时候,发生的其他错误可能就是python环境少东西导致的,让算法的自己解决吧。

更新:又发现了一种新写法

    PythonEngine.Initialize();
    var pyThread = PythonEngine.BeginAllowThreads();
    var pyLock = PythonEngine.AcquireLock();//多线程调用,先锁定线程,最后再释放线程 功能同using (Py.GIL()){}

  PyObject pModule = PythonEngine.ImportModule("mytest0.main"); var a = pModule.InvokeMethod("recognize", @"D:/16.jpg".ToPython()); s = a.ToString();

 

插播一些python环境的小tips:

1.一般是用来深度学习之类的py代码,是从别的机器运行或学习过来的 显卡等GPU环境可能不同,涉及到cuda、torch、torchvision这些包的版本对应一定要配置好,不然会报错。

2.引用路径最好用绝对路径,相对路径我测报错,猜测打包后找不到了

posted @ 2022-08-02 15:30  螺丝起子  阅读(2171)  评论(1编辑  收藏  举报