【问题标题】:Calling a C# library from python从 python 调用 C# 库
【发布时间】: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# python interop ironpython python.net


【解决方案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
  • 如果您在 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
    猜你喜欢
    • 1970-01-01
    • 2014-10-19
    • 2019-12-19
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多