在Python中调用C#库

62 投票
5 回答
119024 浏览
提问于 2025-04-17 01:56

有没有人能分享一个简单的例子,教我怎么从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代码调用这个代码。有什么建议吗?

5 个回答

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

24

因为你的帖子标记了IronPython,如果你想使用示例中的C#代码,下面的内容应该可以正常工作。

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

p = PlotData()
p.Start()
51

其实这很简单。只需要通过NuGet给你的.Net项目添加一个叫“UnmanagedExports”的包就可以了。具体的步骤可以参考这个链接: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;
    }
}

然后你可以在Python中加载这个dll,并调用那些暴露出来的方法(适用于2.7版本)。

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

撰写回答