2010-06-09 16 views
6

Estoy tratando de utilizar IronPython como intermediario entre una GUI de C# y algunas bibliotecas de C#, de modo que pueda escribirse el tiempo de compilación posterior.C#/IronPython Interop con biblioteca de clases de C# compartida

Tengo una biblioteca DLL de clase que se utiliza por tanto la interfaz gráfica de usuario y la pitón y es algo a lo largo de las líneas de esto:

namespace MyLib 
{ 
    public class MyClass 
    { 
     public string Name { get; set; } 
     public MyClass(string name) 
     { 
      this.Name = name; 
     } 
    } 
} 

El código IronPython es el siguiente:

import clr 
clr.AddReferenceToFile(r"MyLib.dll") 
from MyLib import MyClass 

ReturnObject = MyClass("Test") 

Luego, en C# yo diría que es de la siguiente manera:

ScriptEngine engine = Python.CreateEngine(); 
ScriptScope scope = null; 

scope = engine.CreateScope(); 
ScriptSource source = engine.CreateScriptSourceFromFile("Script.py"); 

source.Execute(scope); 

MyClass mc = scope.GetVariable<MyClass>("ReturnObject ") 

Cuando llamo a este último bit de código, source.Ex ecute (alcance) se ejecuta devuelve correctamente, pero cuando trato de la llamada GetVariable, es la excepción siguiente

Microsoft.Scripting.ArgumentTypeException: expected MyClass , got MyClass 

Por lo tanto, se puede ver que los nombres de las clases son exactamente lo mismo, pero por alguna razón se cree que son diferente.

La DLL está en un directorio diferente que el archivo .py (simplemente no me molesté en escribir todas las cosas de configuración de la ruta), podría ser que haya un problema con el intérprete para que IronPython vea estos objetos como diferencia porque de alguna manera los ve como en un contexto o alcance diferente?

Respuesta

11

Este error indica que su conjunto se está cargando en múltiples contextos de cargador CLR. En lugar de agregar la referencia usando clr.AddReferenceToFile, puede cambiar a clr.AddReference o puede cargar el ensamblaje desde C#. Para el primero, debe asegurarse de que el ensamblado esté disponible en algún lugar donde normalmente .NET pueda cargarlo (el GAC o en la base de la aplicación del proceso). Para este último, puede hacer:

engine.Runtime.LoadAssembly(typeof(MyClass).Assembly); 

desde su código de host C#. Personalmente, me gusta esta segunda solución un poco más porque no solo funciona, sino que también evita que los usuarios tengan que hacer la llamada clr.AddRef desde Python.

1

Puede intentar ejecutar su programa bajo el depurador y interrumpir la ejecución antes de la llamada GetVariable. Vaya a la ventana de "módulos" y vea si hay dos versiones de su biblioteca de clases C# cargadas. Si ese es el caso, entonces esa es la explicación.

Si ese es el problema, entonces la solución es asegurarse de que los mundos de C# y Python estén de acuerdo en los tipos. Una solución es poner todo en el mismo directorio. Otra posibilidad es configurar una referencia a su biblioteca de clase en C# utilizando las propiedades de la clase ScriptScope (creo) para establecer una referencia de ensamblaje para su conjunto de biblioteca de clase que estará disponible para el código de Python. No tengo un proyecto híbrido C#/IronPython inmediatamente disponible para probar, pero recuerdo haber visto esa funcionalidad.

Cuestiones relacionadas