2011-09-09 28 views
31

¿Alguien puede compartir un ejemplo práctico sobre cómo llamar a una biblioteca simple de C# (en realidad su WPF) desde el código python? (He intentado usar IronPython y tuve demasiados problemas con la biblioteca de CPython no compatible que usa mi código python, así que pensé en intentar hacer lo contrario y llamar a mi código C# desde Python).Llamar a una biblioteca de C# desde python

Aquí es el ejemplo que estaba jugando con:

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 es una ventana de WPF que traza una elipse

no sé cómo llamar a este código de mi pitón todos. ¿Alguna sugerencia?

+0

Se puede usar un C++/CLI envoltorio. Consulte http://stackoverflow.com/a/42930903/1178267 como respuesta de referencia – anhoppe

Respuesta

2

No soy un experto en .NET, pero su código se ve como si su método estuviera expuesto como un objeto COM. Así que puedes probar el paquete http://starship.python.net/crew/mhammond/win32/ para acceder a él.

+0

Usted * puede * exponer sus objetos .NET como objetos COM, pero hay un golpe de rendimiento, y no es el predeterminado. - Además, si lo haces mal, puede provocar pérdidas de memoria. - En general, solo usaría este enfoque para la compatibilidad con versiones anteriores, como si estuviera integrando con una tecnología anterior que ya sea compatible con COM. - Además, huelga decir que, si adoptas este enfoque, estás completamente limitado a la plataforma de Windows. – BrainSlugs83

10

Python para .Net (pythonnet) puede ser una alternativa razonable a IronPython en su situación. https://github.com/pythonnet/pythonnet/blob/master/README.md

Desde el sitio:

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.

también

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.

Este paquete todavía requiere que tenga un tiempo de ejecución CPython local de la máquina. Consulte el archivo Léame completo para obtener más información http://pythonnet.github.io/readme.html

12

Dado que su publicación está etiquetada IronPython, si desea utilizar la muestra C#, lo siguiente debería funcionar.

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

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

El mismo código funciona con las últimas versiones de Python para .Net. Es bueno saber que ambas soluciones (IronPython y CPython + PythonNet) funcionan de la misma manera. – Vincent

27

En realidad es bastante fácil. Simplemente use NuGet para agregar el paquete "UnmanagedExports" a su proyecto .Net. Vea https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports para más detalles.

Puede exportar directamente, sin tener que hacer una capa COM. Aquí está el ejemplo de código 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; 
    } 
} 

, puede cargar el archivo DLL y llamar a los métodos expuestos en Python (que funciona para 2,7)

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

Muy genial si tienes el control de la biblioteca. Si no, imagino que puedes hacer un .dll envoltorio con la convención de llamadas al estilo C. – CodeMonkey

+2

Recibí el próximo error: AttributeError: no se encontró la función 'add' – constructor

+3

ver nota importante: http://stackoverflow.com/questions/34417972/no-functions-in-c-sharp-dll-with-rgiesecke-dllexport – constructor

7

Este proyecto ha sido desarrollado para ese propósito exacto - uso clases de C# en Python regulares

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

Todo lo que necesita hacer es instalar cualquiera de MSI o el huevo en su CPython. PyDotnet es el módulo de Python, por lo que el ejecutable se mantiene regular python.exe desde su instalación de Python o Anaconda. Compatible con 32 bits y 64 bits.

Acceso ilimitado a todas las clases C#, métodos con parámetros de salida y ref, clases genéricas y métodos genéricos, métodos de extensión, miembros privados.

Cargador de ensamblaje sobrecargado con mecanismos personalizados para la búsqueda de conjuntos.

Información del tipo de tiempo de ejecución de .NET convertible en objeto de clase, que se puede instanciar como cualquier otra clase.

modo de importación especial diseñado especialmente para Python shell interactivo, que permite descubrir montajes disponibles, espacios de nombres, clases, métodos, etc.

estoy en espera de retroalimentación :)

+0

> >> importar dotnet.seamless Traceback (última llamada más reciente): Archivo "", línea 1, en Archivo "C: \ Archivos de programa \ Python35-32 \ lib \ site-packages \ dotnet \ __ init__.py ", línea 21, en importación dotnet.moduleloader archivo "C: \ archivos de programa \ Python35-32 \ lib \ site-packages \ dotnet \ moduleloader.py", línea 24, en de dotnet PyDotnet importación como _dotnet ImportError: error en la carga DLL: el módulo especificado co uld no ser encontrado. –