【问题标题】:How to pass a dynamic list from IronPython to C#如何将动态列表从 IronPython 传递到 C#
【发布时间】:2021-03-03 05:19:32
【问题描述】:

我想要一个 python 应用程序将通用列表传递给我的 C# 代码。我创建了一个演示应用程序,复制了我看到的问题。

我有这个 python 代码 (Python 2.7) MainApp.py,它调用了一个 C# DLL (.NET 4.7):

import clr, sys

sys.path.append(r"C:\PathToMyProject\ClassLibrary1\bin\Debug")
clr.AddReference(r"C:\PathToMyProject\ClassLibrary1\bin\Debug\ClassLibrary1.dll")

from ClassLibrary1 import Class1

class Person:
    def __init__(self, Name):
        self.Name = Name


myclass = Class1()

nameList = []
nameList.append(Person("Joe"))
nameList.append(Person("Mary"))
nameList.append(Person("Chris"))

result = myclass.SayHello(nameList)

print(result)

请注意,我有一个 Person 对象列表 nameList,我正在尝试传递。这是 C# 代码:

using System.Collections.Generic;

namespace ClassLibrary1
{
    public class Class1
    {
        public string SayHello(List<dynamic> names)
        {
            return $"Hello, {names.Count} people!";
        }
    }
}

SayHello 方法接受List&lt;dynamic&gt; 的参数。但是,我在运行&gt;python MainApp.py 时收到以下错误:

Traceback(最近一次调用最后一次):文件“.\MainApp.py”,第 20 行,在 结果 = myclass.SayHello(nameList) TypeError: 没有方法匹配 SayHello 的给定参数: ()

【问题讨论】:

    标签: python c# ironpython dynamic-language-runtime


    【解决方案1】:

    我用下面的代码解决了:

    MainApp.py:

    import clr, sys
    
    sys.path.append(r"C:\Projects\temp\ClassLibrary1\bin\Debug")
    clr.AddReference(r"C:\Projects\temp\ClassLibrary1\bin\Debug\ClassLibrary1.dll")
    
    from ClassLibrary1 import Class1
    from ClassLibrary1 import Person
    
    myclass = Class1()
    
    nameList = []
    nameList.append(Person("Joe"))
    nameList.append(Person("Mary"))
    nameList.append(Person("Chris"))
    
    result = myclass.SayHello(nameList)
    
    print(result)
    

    Class1.cs:

    namespace ClassLibrary1
    {
        public class Class1
        {
            public string SayHello(dynamic[] names)
            {
                foreach (var item in names)
                {
                    System.Console.WriteLine(item.Name);
                }
    
                return $"Hello, {names.Length} people!";
            }
        }
    
        public class Person
        {
            public Person(string name)
            {
                Name = name;
            }
    
            public string Name { get; set; }
        }
    }
    

    我做的第一件事是将SayHello 参数类型从List&lt;dynamic&gt; 更改为dynamic[]

    public string SayHello(dynamic[] names)
    

    修复了类型错误,但我开始收到一条新消息:

    未处理的异常:System.Reflection.TargetInvocationException: 调用的目标已引发异常。 ---> System.AccessViolationException:试图读或写保护 记忆。这通常表明其他内存已损坏。
    在 Python.Runtime.Runtime.PyObject_GetAttrString(IntPtr 指针, 字符串名称)在 Python.Runtime.PyObject.GetAttr(字符串名称)在 Python.Runtime.PyObject.TryGetMember(GetMemberBinder binder, Object& 结果) 在 CallSite.Target(Closure , CallSite , Object ) 在 System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,Tret](CallSite 站点,T0 arg0) 在 ClassLibrary1.Class1.SayHello(Object[] names) 中 C:\Projects\csharp-nine-cookbook\csharp-nine-cookbook\CSharp9Cookbook\ClassLibrary1\Class1.cs:line 11 --- 内部异常堆栈跟踪结束 --- 在 System.RuntimeMethodHandle.InvokeMethod(对象目标,对象 [] 参数,签名 sig,布尔构造函数)在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象 obj, Object[] 参数,Object[] 参数)在 System.Reflection.RuntimeMethodInfo.Invoke(对象 obj,BindingFlags invokeAttr、Binder binder、Object[] 参数、CultureInfo 文化)
    在 Python.Runtime.MethodBinder.Invoke(IntPtr inst,IntPtr args,IntPtr kw, MethodBase 信息, MethodInfo[] methodinfo) 在 Python.Runtime.MethodObject.Invoke(IntPtr 目标,IntPtr 参数,IntPtr kw,MethodBase 信息)在 Python.Runtime.MethodBinding.tp_call(IntPtr ob, IntPtr args, IntPtr kw)

    显然 IronPython 不允许我将自定义类型从 python 传递到 C#。为了解决这个问题,我在 C# 代码中添加了一个 Person 类:

    public class Person
    {
        public Person(string name)
        {
            Name = name;
        }
    
        public string Name { get; set; }
    }
    

    然后我从 python 代码中删除了自定义的 Person 类,并在 C# 代码中引用了该类:

    from ClassLibrary1 import Person
    

    之后一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 2014-07-14
      • 1970-01-01
      • 2019-01-26
      • 2010-10-24
      • 2011-01-14
      相关资源
      最近更新 更多