Вызов библиотеки C# из python
Кто-нибудь может поделиться рабочим примером того, как вызвать простую библиотеку C# (фактически ее WPF) из кода Python? (Я пытался использовать IronPython, и у меня было слишком много проблем с неподдерживаемой библиотекой CPython, которую использует мой код на python, поэтому я подумал о том, чтобы попробовать другой способ и вызвать мой код C# из Python).
Вот пример, с которым я играл:
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();
}
}
}
Плоттер - это окна WPF, которые строят эллипс
Я не знаю, как вызвать этот код из моего питона все. Какие-либо предложения?
6 ответов
Это на самом деле довольно легко. Просто используйте 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)
Поскольку ваш пост помечен IronPython, если вы хотите использовать пример C#, должно работать следующее.
import clr
clr.AddReference('assembly name here')
from DataViewerLibrary import PlotData
p = PlotData()
p.Start()
Python для.Net (pythonnet) может быть разумной альтернативой IronPython в вашей ситуации. https://github.com/pythonnet/pythonnet/blob/master/README.md
С сайта:
Обратите внимание, что этот пакет не реализует Python как первоклассный язык CLR - он не создает управляемый код (IL) из кода Python. Скорее, это интеграция движка CPython со средой исполнения.NET. Этот подход позволяет использовать службы CLR и продолжать использовать существующий код Python и расширения на основе C, сохраняя при этом собственные скорости выполнения кода Python.
Также
Python для.NET использует PYTHONPATH (sys.path) для поиска загружаемых сборок в дополнение к обычной базе приложений и GAC. Чтобы гарантировать возможность неявного импорта сборки, поместите каталог, содержащий эту сборку, в sys.path.
Этот пакет по-прежнему требует наличия локальной среды выполнения CPython на вашем компьютере. См. Полный файл Readme для получения дополнительной информации http://pythonnet.github.io/readme.html
Этот проект был разработан именно для этой цели - используйте классы C# в обычном Python
https://bitbucket.org/pydotnet/pydotnet/wiki/Home
Все, что вам нужно сделать, это установить MSI или EGG в ваш CPython. PyDotnet - это модуль Python, поэтому исполняемый файл остается обычным python.exe из вашей установки Python или Anaconda. Поддерживаются как 32-битные, так и 64-битные.
Неограниченный доступ ко всем классам C#, методам с параметрами output и ref, универсальным классам и универсальным методам, методам расширения, закрытым членам.
Перегруженный сборочный загрузчик с настраиваемой механикой для поиска сборок.
Информация о типе среды выполнения.NET, преобразуемая в объект класса, который может быть создан как любой другой класс.
Специальный режим импорта, разработанный специально для интерактивной оболочки Python, который позволяет обнаруживать доступные сборки, пространства имен, классы, методы и т. Д.
Жду отзывов:)
Майкл Бейкер уже дал правильный ответ.
Вот рабочий пример:
Код C# ClassLibrary:
(не забудьте ключевое слово public и обратите внимание на пространство имен, оно станет именем модуля Python)
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\bin\Debug\net7.0\MyDotNetClassLib.dll"
Файл Python : ".\PythonApplication\PythonApplication.py"
добавляет путь к файлу dll.
AddReference имя сборки (обычно имя файла dll без .dll)
. Импортирует модуль (который является пространством имен C#).
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)}")
Вывод консоли при вызове:
PS PythonApplication> python .\PythonApplication.py
hello from python
hello from C#
My C# Adder static: 3
My C# Adder method: 7
Скомпилировано и запущено с помощью:
- ПРОТИВ 2022/.NET 7.0
- Python 3.10.11 (и не забудьте «pip install pythonnet»)
Я не эксперт.NET, но ваш код выглядит так, как будто ваш метод представлен как объект COM. Таким образом, вы можете попробовать пакет http://starship.python.net/crew/mhammond/win32/, чтобы получить к нему доступ.