任何人都可以分享一个关于如何从 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 中调用这段代码。有什么建议么?
其实很简单。只需使用 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)
由于您的帖子被标记为 IronPython,因此如果您想使用示例 C#,则以下内容应该可以工作。
import clr
clr.AddReference('assembly name here')
from DataViewerLibrary import PlotData
p = PlotData()
p.Start()
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
这个项目就是为了这个目的而开发的 - 在常规 Python 中使用 C# 类
https://bitbucket.org/pydotnet/pydotnet/wiki/Home
您所需要做的就是将 MSI 或 EGG 安装到您的 CPython 中。 PyDotnet 是 Python 模块,因此可执行文件保持 Python 或 Anaconda 安装中的常规 python.exe。支持 32 位和 64 位。
无限制访问所有 C# 类、带有输出和引用参数的方法、泛型类和泛型方法、扩展方法、私有成员。
重载的程序集加载器,具有用于搜索程序集的自定义机制。
.NET 运行时类型信息可转换为类对象,可以像任何其他类一样实例化。
专为 Python 交互式 shell 设计的特殊导入模式,允许您发现可用的程序集、命名空间、类、方法等。
我正在等待反馈:)
迈克尔·贝克已经给出了正确答案。我只想用一个工作示例来扩展它:
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
编译运行: