【问题标题】:C# / IronPython Interop with shared C# Class LibraryC# / IronPython 与共享 C# 类库的互操作
【发布时间】:2010-06-09 19:30:05
【问题描述】:

我正在尝试使用 IronPython 作为 C# GUI 和一些 C# 库之间的中介,以便可以在编译后编写脚本。

我有一个 GUI 和 python 都使用的类库 DLL,它是这样的:

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 的解释器将这些对象视为差异存在问题因为它以某种方式将它们视为处于不同的上下文或范围?

【问题讨论】:

    标签: c# interop ironpython c#-4.0


    【解决方案1】:

    此错误表明您的程序集正在加载到多个 CLR 加载器上下文中。您可以切换到 clr.AddReference 或从 C# 加载程序集,而不是使用 clr.AddReferenceToFile 添加引用。对于前者,您需要确保程序集在 .NET 可以正常加载它的地方(GAC 或进程的应用程序库中)可用。对于后者,您可以这样做:

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

    来自您的 C# 主机代码。就我个人而言,我更喜欢第二种解决方案,因为它不仅可以工作,还可以让您的用户无需从 Python 执行 clr.AddRef 调用。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-05-19
        • 2019-04-10
        • 1970-01-01
        • 2010-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多