Я пытаюсь использовать IronPython в качестве посредника между GUI C# и некоторыми библиотеками C#, так, чтобы он мог быть задан сценарием время компиляции сообщения.
У меня есть Библиотека классов DLL, который используется и GUI и Python и является чем-то вроде этого:
namespace MyLib
{
public class MyClass
{
public string Name { get; set; }
public MyClass(string name)
{
this.Name = name;
}
}
}
Код IronPython следующие:
import clr
clr.AddReferenceToFile(r"MyLib.dll")
from MyLib import MyClass
ReturnObject = MyClass("Test")
Затем в C# я назвал бы его следующим образом:
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 ")
Когда я называю этот последний бит кода, источника. Выполнитесь (определяют объем) возвратов выполнений успешно, но когда я пробую вызов GetVariable, он выдает следующее исключение
Microsoft.Scripting.ArgumentTypeException: expected MyClass , got MyClass
Так, Вы видите, что имена классов являются точно тем же, но по некоторым причинам оно думает, что они отличаются.
DLL находится в другом каталоге, чем .py файл (я просто не потрудился выписывать весь материал установки тракта), могло случиться так, что существует проблема с интерпретатором для IronPython, рассматривая эти объекты как различие, потому что он так или иначе видит их как являющийся в другом контексте или объеме?
Эта ошибка означает, что ваша сборка загружается в несколько контекстов загрузчика CLR. Вместо добавления ссылки с помощью clr.AddReferenceToFile вы можете либо переключиться на clr.AddReference, либо загрузить сборку из C #. Для первого вам необходимо убедиться, что сборка доступна где-то, где .NET может ее нормально загрузить (GAC или в базе приложения процесса). Для последнего вы можете просто сделать:
engine.Runtime.LoadAssembly(typeof(MyClass).Assembly);
из кода вашего хоста C #. Лично мне это второе решение нравится немного больше, потому что оно не только работает, но и избавляет ваших пользователей от необходимости выполнять вызов clr.AddRef из Python.
Вы можете попробовать запустить свою программу под отладчиком и прервать выполнение до вызова GetVariable. Перейдите в окно «модули» и посмотрите, загружены ли две версии вашей библиотеки классов C #. Если это так, то это объяснение.
Если проблема в этом, то решение состоит в том, чтобы убедиться, что в мирах C # и Python согласованы типы. Одно из решений - поместить все в один каталог. Другая возможность - настроить ссылку на вашу библиотеку классов на C #, используя свойства класса ScriptScope (я думаю), чтобы установить ссылку на сборку вашей библиотеки классов, которая будет доступна для кода Python. У меня нет гибридного проекта C # / IronPython, который можно было бы сразу протестировать, но я помню, что видел эту функциональность.