C # / IronPython Interop с общей библиотекой классов C # - PullRequest
6 голосов
/ 09 июня 2010

Я пытаюсь использовать IronPython в качестве посредника между графическим интерфейсом 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 ")

Когда я вызываю этот последний бит кода, source.Execute (scope) возвращается успешно, но при попытке вызова GetVariable выдает следующее исключение

Microsoft.Scripting.ArgumentTypeException: expected MyClass , got MyClass 

Вы можете видеть, что имена классов точно такие же, но по какой-то причине они думают, что они разные.

DLL находится в другом каталоге, чем файл .py (я просто не удосужился написатьвсе настройки пути), может ли быть проблема с интерпретатором для IronPython, который видит эти объекты как различия, потому что он каким-то образом видит их в другом контексте или области видимости?

Ответы [ 2 ]

11 голосов
/ 10 июня 2010

Эта ошибка означает, что ваша сборка загружается в несколько контекстов загрузчика CLR. Вместо добавления ссылки с помощью clr.AddReferenceToFile вы можете либо переключиться на clr.AddReference, либо загрузить сборку из C #. В первом случае вам нужно убедиться, что сборка доступна где-то, что .NET может нормально ее загрузить (GAC или в базе приложения процесса). Для последнего вы можете просто сделать:

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

из вашего кода хоста C #. Лично мне больше нравится это второе решение, потому что оно не только работает, но и избавляет ваших пользователей от необходимости выполнять вызов clr.AddRef из Python.

1 голос
/ 10 июня 2010

Вы можете попробовать запустить вашу программу под отладчиком и прервать выполнение до вызова GetVariable. Перейдите в окно «модули» и посмотрите, загружены ли две версии вашей библиотеки библиотек классов C #. Если это так, то это объяснение.

Если это проблема, то решение состоит в том, чтобы убедиться, что миры C # и Python согласовывают типы. Одним из решений является поместить все в один каталог. Другая возможность - установить ссылку на вашу библиотеку классов в C #, используя свойства класса ScriptScope (я думаю), чтобы установить ссылку на сборку вашей библиотеки классов, которая будет доступна для кода Python. У меня нет гибридного проекта C # / IronPython, сразу доступного для тестирования, но я помню, что видел эту функциональность.

...