从 python 调用 C# 库

问题描述 投票:0回答:5

任何人都可以分享一个关于如何从 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
5个回答
49
投票

其实很简单。只需使用 NuGet 将“UnmanagementExports”包添加到您的 .Net 项目中即可。有关详细信息,请参阅 https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagementexports

然后可以直接导出,无需做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)

24
投票

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

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

p = PlotData()
p.Start()

17
投票

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

来自网站:

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

还有

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

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


10
投票

这个项目就是为了这个目的而开发的 - 在常规 Python 中使用 C# 类

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

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

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

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

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

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

我正在等待反馈:)


0
投票

迈克尔·贝克已经给出了正确答案。我只想用一个工作示例来扩展它:

C# ClassLibrary code: 

    namespace MyDotNetClassLib
    {
        public class Adder
        {
            public static int StaticAdd(int left, int right)
            {
                return left + right;
            }
            public int Add(int left, int right)
            {
                return left + right;
            }
        }
    }

输出生成为“.\MyDotNetClassLib in\Debug” et7.0\MyDotNetClassLib.dll"

Python 文件:“.\PythonApplication\PythonApplication.py”

    import clr
    from System import Console
    #from System import String
    #from System.Collections import *
    
    import sys
    sys.path.append('../MyDotNetClassLib/bin/Debug/net7.0/')
    clr.AddReference("MyDotNetClassLib")
    from MyDotNetClassLib import Adder 
    
    
    print()
    print("hello from python")
    Console.WriteLine("hello from C#")
    
    print(f"My C# Adder static: {Adder.StaticAdd(1,2)}")
    
    adder = Adder()
    print(f"My C# Adder method: {adder.Add(3,4)}")
Output when called:

    PS PythonApplication> python .\PythonApplication.py

    hello from python
    hello from C#
    My C# Adder static: 3
    My C# Adder method: 7

编译运行:

  • VS 2022 / .NET 7.0
  • Python 3.10.11(并且不要忘记“pip install pythonnet”)
© www.soinside.com 2019 - 2024. All rights reserved.