2010-06-09 3 views
6

Sto cercando di utilizzare IronPython come intermediario tra una GUI C# e alcune librerie C#, in modo che possa essere copiato in fase di compilazione.C#/IronPython Interop con libreria di classi C# condivisa

Ho una libreria di classi DLL che viene utilizzato sia dalla GUI e il pitone ed è qualcosa sulla falsariga di questo:

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

Il codice di IronPython è la seguente:

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

ReturnObject = MyClass("Test") 

poi, in C# che definirei come segue:

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 ") 

Quando chiamo questo ultimo pezzo di codice, source.Ex ecute (campo di applicazione) gestisce ritorna con successo, ma quando provo la chiamata GetVariable, è gettare la seguente eccezione

Microsoft.Scripting.ArgumentTypeException: expected MyClass , got MyClass 

Così, si può vedere che i nomi di classe sono esattamente gli stessi, ma per qualche motivo si pensa che siano diverso.

La DLL si trova in una directory diversa da quella del file .py (non mi sono preoccupato di scrivere tutte le impostazioni del percorso), potrebbe essere che ci sia un problema con l'interprete per IronPython vedere questi oggetti come differenza perché è in qualche modo vederli come in un contesto o scopo diverso?

risposta

11

Questo errore indica che l'assembly viene caricato in più contesti del caricatore CLR. Piuttosto che aggiungere il riferimento utilizzando clr.AddReferenceToFile, puoi passare a clr.AddReference oppure caricare l'assembly da C#. Per il primo è necessario assicurarsi che l'assembly sia disponibile da qualche parte che .NET può normalmente caricarlo (il GAC o nella base dell'applicazione del processo). Per il secondo è sufficiente fare:

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

dal codice host C#. Personalmente questa seconda soluzione mi piace un po 'di più perché non solo funziona, ma salva gli utenti dal dover eseguire la chiamata clr.AddRef da Python.

1

Si potrebbe provare a eseguire il programma sotto il debugger e interrompere l'esecuzione prima della chiamata GetVariable. Vai alla finestra "modules" e controlla se ci sono due versioni della libreria di classi C# caricate. Se è così, allora questa è la spiegazione.

Se questo è il problema, la soluzione è assicurarsi che i mondi C# e Python siano d'accordo sui tipi. Una soluzione è mettere tutto nella stessa directory. Un'altra possibilità è quella di impostare un riferimento alla libreria di classi in C# utilizzando le proprietà sulla classe ScriptScope (credo) per impostare un riferimento all'assembly dell'assembly della libreria di classi che sarà disponibile per il codice Python. Non ho un progetto ibrido C#/IronPython immediatamente disponibile per il test, ma ricordo di aver visto questa funzionalità.