2011-09-09 11 views
31

Ktoś może udostępnić działający przykład, jak wywołać prostą bibliotekę C# (a właściwie jej WPF) z kodu Pythona? (Próbowałem używać IronPython i miałem zbyt dużo problemów z nieobsługiwaną biblioteką CPython, której używa mój kod Pythona, więc pomyślałem o próbie odwrotnej sytuacji i wywołaniu mojego kodu C# z Pythona).Wywoływanie biblioteki języka C# z Pythona

Oto przykład grałem z:

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(); 
     } 
    } 
} 

Ploter to windows WPF, że działki elipsę

nie wiem jak nazwać ten kod z mojego pytona wszystko. Jakieś sugestie?

+0

można użyć C++/Wrapper CLI. Zobacz http://stackoverflow.com/a/42930903/1178267 jako odpowiedź referencyjna – anhoppe

Odpowiedz

2

Nie jestem ekspertem od technologii .NET, ale kod wygląda tak, jakby Twoja metoda została ujawniona jako obiekt COM. Możesz więc wypróbować pakiet http://starship.python.net/crew/mhammond/win32/, aby uzyskać do niego dostęp.

+0

Możesz * wystawiać * swoje obiekty .NET jako obiekty COM, ale istnieje wydajność, która nie jest domyślna. - Jeśli zrobisz to źle, może to prowadzić do przecieków pamięci. - Zasadniczo stosowałbyś to podejście tylko w celu zapewnienia kompatybilności wstecznej, tak jak w przypadku integracji ze starszą technologią, która obsługuje już COM. - Ponadto oczywiste jest, że jeśli podejmiesz takie podejście, całkowicie ograniczysz się do platformy Windows. – BrainSlugs83

10

Python dla .Net (pythonnet) może być rozsądną alternatywą dla IronPythona w twojej sytuacji. https://github.com/pythonnet/pythonnet/blob/master/README.md

Z witryny:

Note that this package does not implement Python as a first-class CLR language - it does not produce managed code (IL) from Python code. Rather, it is an integration of the CPython engine with the .NET runtime. This approach allows you to use use CLR services and continue to use existing Python code and C-based extensions while maintaining native execution speeds for Python code.

także

Python for .NET uses the PYTHONPATH (sys.path) to look for assemblies to load, in addition to the usual application base and the GAC. To ensure that you can implicitly import an assembly, put the directory containing the assembly in sys.path.

Pakiet ten nadal wymaga posiadania lokalnego środowiska wykonawczego CPython na komputerze. Zobacz pełny plik Readme, aby uzyskać więcej informacji. http://pythonnet.github.io/readme.html

12

Ponieważ Twój post jest oznaczony jako IronPython, jeśli chcesz użyć przykładowego C#, powinny działać następujące elementy.

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

p = PlotData() 
p.Start() 
+3

Ten sam kod działa z ostatnimi wydaniami Pythona dla .Net. Dobrze wiedzieć, że oba rozwiązania (IronPython i CPython + PythonNet) działają w ten sam sposób. – Vincent

27

To jest naprawdę łatwe. Po prostu użyj NuGet, aby dodać pakiet "UnmanagedExports" do swojego projektu .Net. Aby uzyskać szczegółowe informacje, patrz: https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports.

Można następnie eksportować bezpośrednio, bez konieczności wykonywania warstwy COM. Oto przykładowy kod 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; 
    } 
} 

Następnie można załadować biblioteki DLL i wywołać odsłonięte metody w Pythonie (działa do 2,7)

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

Bardzo fajnie, jeśli masz kontrolę nad biblioteką. Jeśli nie, wyobrażam sobie, że możesz stworzyć plik .dll z konwencją wywoływania w stylu C. – CodeMonkey

+2

Otrzymałem następny błąd: AttributeError: funkcja 'add' nie została znaleziona – constructor

+3

patrz ważna uwaga: http://stackoverflow.com/questions/34417972/no-functions-in-c-sharp-dll-with-rgieseck-dllexport – constructor

7

Projekt ten został opracowany dla tego dokładnego celu - wykorzystanie C# klas w regularnych Python

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

Wszystko, co musisz zrobić, to zainstalować albo MSI lub jajko do swojej CPython. PyDotnet to moduł Pythona, więc plik wykonywalny pozostaje regularny z python.exe z instalacji Pythona lub Anacondy. Obsługiwane zarówno 32-bitowe, jak i 64-bitowe.

Nieograniczony dostęp do wszystkich klas C#, metod z parametrami wyjściowymi i parametrami ref, klas ogólnych i metod ogólnych, metod rozszerzeń, elementów prywatnych.

Przeciążony moduł ładujący z dostosowaną mechaniką do wyszukiwania złożeń.

. Informacje o typie środowiska wykonawczego .NET, które można przekształcić w obiekt klasy, można utworzyć instancję jak każdą inną klasę.

Specjalny tryb import zaprojektowany specjalnie dla Pythona interaktywnej powłoki, która pozwala odkryć dostępnych zespołów, nazw, klas, metod itp

czekam na informacje zwrotne :)

+0

> >> import dotnet.seamless Traceback (ostatnie ostatnie połączenie): Plik "", wiersz 1, w Plik "C: \ Program Files \ Python35-32 \ lib \ site-packages \ dotnet \ __ init__.py ”, linia 21, w import dotnet.moduleloader pliku "C: Program Files \ \ Python35-32 \ lib \ site-packages \ DotNet \ moduleloader.py", linia 24, w z dotnet importowej PyDotnet jak _dotnet ImportError: Błąd ładowania biblioteki DLL: podany moduł co nie można znaleźć. –

Powiązane problemy