簡體   English   中英

C#/ IronPython與共享C#類庫互操作

[英]C# / IronPython Interop with shared C# Class Library

我正在嘗試使用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的解釋器出現問題,看到這些對象是不同的,因為它是某種方式看到他們處於不同的背景或范圍?

此錯誤表示您的程序集已加載到多個CLR加載程序上下文中。 您可以切換到clr.AddReference,也可以從C#加載程序集,而不是使用clr.AddReferenceToFile添加引用。 對於前者,您需要確保程序集在.NET可以正常加載的位置(GAC或進程的應用程序庫)中可用。 對於后者你可以這樣做:

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

來自您的C#主機代碼。 就個人而言,我更喜歡這個第二個解決方案,因為它不僅可以幫助您節省用戶從Python進行clr.AddRef調用。

您可以嘗試在調試器下運行程序並在GetVariable調用之前中斷執行。 轉到“模塊”窗口,查看是否加載了兩個版本的C#類庫DLL。 如果是這樣,那就是解釋。

如果這就是問題,那么解決方案是確保C#和Python世界在類型上達成一致。 一種解決方案是將所有內容放在同一目錄中。 另一種可能性是通過使用ScriptScope類(我認為)上的屬性來設置對C#中類庫的引用,以設置可供Python代碼使用的類庫程序集的程序集引用。 我沒有立即可用於測試的混合C#/ IronPython項目,但我記得看到了這個功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM