从 python 调用 C# 库

Posted

技术标签:

【中文标题】从 python 调用 C# 库【英文标题】:Calling a C# library from python 【发布时间】:2011-11-14 03:24:45 【问题描述】:

任何人都可以分享一个关于如何从 python 代码调用简单的 C# 库(实际上是它的 WPF)的工作示例? (我尝试过使用 IronPython 并且在我的 python 代码正在使用的不受支持的 CPython 库上遇到了太多麻烦,所以我想尝试另一种方式并从 Python 调用我的 C# 代码)。

这是我正在玩的示例:

using System.Runtime.InteropServices;
using System.EnterpriseServices;

namespace DataViewerLibrary

    public interface ISimpleProvider
    
       [DispIdAttribute(0)]
       void Start();
    

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class PlotData : ServicedComponent, ISimpleProvider
    
       public void Start()
       
          Plot plotter = new Plot();
          plotter.ShowDialog();
       
    

Plotter 是一个绘制椭圆的 WPF 窗口

我不知道如何从我的 python 中调用这段代码。有什么建议?

【问题讨论】:

您可以使用 C++/CLI 包装器。请参阅***.com/a/42930903/1178267 作为参考答案 【参考方案1】:

其实很简单。只需使用 NuGet 将“UnmanagedExports”包添加到您的 .Net 项目。详情请见https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports。

然后您可以直接导出,而无需执行 COM 层。这是示例 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using RGiesecke.DllExport;

class Test

    [DllExport("add", CallingConvention = CallingConvention.Cdecl)]
    public static int TestExport(int left, int right)
    
        return left + right;
    

然后您可以加载 dll 并在 Python 中调用公开的方法(适用于 2.7)

import ctypes
a = ctypes.cdll.LoadLibrary(source)
a.add(3, 5)

【讨论】:

如果你能控制图书馆,那就太棒了。如果不是,我想您可以使用 C 风格的调用约定制作一个包装器 .dll。 我收到下一个错误:AttributeError: function 'add' not found 见重要说明:***.com/questions/34417972/… 如果您在 Python 中看到错误 AttributeError: function 'add' not found,那是因为它不适用于 Any CPU。要解决此问题,请将构建类型设置为 x32x64(取决于您的 Python 版本)。然后指向右边的.dll,例如在x64\Release 文件夹中。 我在 x64 中构建了我的 c# dll。 dll 已在两个文件夹 obj 和 bin 中创建。如果我使用 bin 中的 dll,我会收到 clr 异常“发生异常:OSError [WinError -532462766] Windows 错误 0xe0434352” /跨度> 【参考方案2】:

由于您的帖子被标记为 IronPython,如果您想使用示例 C#,以下应该可以工作。

import clr
clr.AddReference('assembly name here')
from DataViewerLibrary import PlotData 

p = PlotData()
p.Start()

【讨论】:

完全相同的代码适用于最新版本的 Python for .Net。很高兴知道这两种解决方案(IronPython 和 CPython+PythonNet)的工作方式相同。【参考方案3】:

Python for .Net (pythonnet) 在您的情况下可能是 IronPython 的合理替代方案。 https://github.com/pythonnet/pythonnet/blob/master/README.rst

来自网站:

请注意,此包并未将 Python 实现为一流的 CLR 语言 - 它不会从 Python 代码生成托管代码 (IL)。 相反,它是 CPython 引擎与 .NET 的集成 运行。这种方法允许您使用 CLR 服务并继续 在维护的同时使用现有的 Python 代码和基于 C 的扩展 Python 代码的本机执行速度。

还有

.NET 的 Python 使用 PYTHONPATH (sys.path) 来查找程序集 加载,除了通常的应用程序库和 GAC。到 确保您可以隐式导入程序集,将目录 在 sys.path 中包含程序集。

这个包仍然要求你的机器上有一个本地 CPython 运行时。 有关更多信息,请参阅完整的自述文件https://github.com/pythonnet/pythonnet

【讨论】:

【参考方案4】:

这个项目正是为此目的而开发的——在常规 Python 中使用 C# 类

https://bitbucket.org/pydotnet/pydotnet/wiki/Home

您需要做的就是将 MSI 或 EGG 安装到您的 CPython 中。 PyDotnet 是 Python 模块,因此可执行文件在您安装 Python 或 Anaconda 时保持常规 python.exe。支持 32 位和 64 位。

无限制地访问所有 C# 类、带有输出和引用参数的方法、泛型类和泛型方法、扩展方法、私有成员。

具有用于搜索程序集的自定义机制的重载程序集加载器。

.NET 运行时类型信息可转换为类对象,可以实例化为任何其他类。

专为 Python 交互式 shell 设计的特殊导入模式,可让您发现可用的程序集、命名空间、类、方法等。

我正在等待反馈:)

【讨论】:

>>> import dotnet.seamless Traceback(最近一次调用最后):文件“”,第 1 行,在 文件“C:\Program Files\Python35-32\lib \site-packages\dotnet_init_.py",第 21 行,在 中 import dotnet.moduleloader File "C:\Program Files\Python35-32\lib\site-packages\dotnet\moduleloader .py",第 24 行,在 中 from dotnet import PyDotnet as _dotnet ImportError: DLL load failed: The specified module could not be found. 快速解决方案 请在 sitepackages\dotnet 中将 boost_python3-vc141-mt-1_64.dll 重命名为 boost_python3-vc150-mt-1_64.dll。更多详情请看这篇文章:bitbucket.org/pydotnet/pydotnet/issues/26/… 比特桶链接此时是404 它在 pypi 上 - 但它缺少对 numpy 的引用,因此如果 pip install numpy 在 pip install pydotnet 之前它可以工作(在 cmd 中作为管理员,只安装了 python3.9.1)。 项目现在在github。

以上是关于从 python 调用 C# 库的主要内容,如果未能解决你的问题,请参考以下文章

从 c# 调用 c++ 库

C#中如何调用动态链接库DLL

从 c++ wrap 调用 c# 方法

(71)C#里怎么样调用C++动态连接库的代码

(71)C#里怎么样调用C++动态连接库的代码

如何从 C# 中的 Python 脚本调用特定方法?