C# / IronPython互操作性与共享C#类库

6
我将尝试使用IronPython作为C# GUI和一些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

这个错误表明你的程序集被加载到了多个CLR加载器上下文中。与其使用clr.AddReferenceToFile添加引用,你可以使用clr.AddReference或者从C#中加载程序集。对于前者,你需要确保程序集可以在.NET通常可以加载的地方可用(如GAC或进程的应用程序基础目录)。对于后者,你只需执行以下操作:

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

个人而言,我更喜欢第二种解决方案,因为它不仅有效,而且可以让用户免除在Python中进行clr.AddRef调用的麻烦,这些都可以从你的C#主机代码中完成。


1

你可以尝试在调试器下运行程序,并在执行 GetVariable 调用之前中断执行。转到“模块”窗口,看看是否加载了两个版本的 C# 类库 DLL。如果是这种情况,那么这就是解释。

如果这是问题所在,那么解决方案是确保 C# 和 Python 世界对类型达成一致。一个解决方案是将所有内容放在同一个目录中。另一个可能性是通过使用 ScriptScope 类的属性(我想)在 C# 中设置对类库的引用,以便 Python 代码可以访问类库程序集。我没有立即可用于测试的混合 C#/IronPython 项目,但我记得看到过这个功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接