如何将动态列表从 IronPython 传递到 C#
How to pass a dynamic list from IronPython to C#
我想要一个 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<dynamic>
。但是,当 运行 >python MainApp.py
:
时,我收到以下错误
Traceback (most recent call last): File ".\MainApp.py", line 20, in
result = myclass.SayHello(nameList) TypeError: No method matches given arguments for SayHello: (<type 'list'>)
我用下面的代码解决了:
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<dynamic>
更改为 dynamic[]
。
public string SayHello(dynamic[] names)
这修复了类型错误,但我开始收到一条新消息:
Unhandled Exception: System.Reflection.TargetInvocationException:
Exception has been thrown by the target of an invocation. --->
System.AccessViolationException: Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
at Python.Runtime.Runtime.PyObject_GetAttrString(IntPtr pointer,
String name) at Python.Runtime.PyObject.GetAttr(String name) at
Python.Runtime.PyObject.TryGetMember(GetMemberBinder binder, Object&
result) at CallSite.Target(Closure , CallSite , Object ) at
System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite
site, T0 arg0) at ClassLibrary1.Class1.SayHello(Object[] names) in
C:\Projects\csharp-nine-cookbook\csharp-nine-cookbook\CSharp9Cookbook\ClassLibrary1\Class1.cs:line
11 --- End of inner exception stack trace --- at
System.RuntimeMethodHandle.InvokeMethod(Object target, Object[]
arguments, Signature sig, Boolean constructor) at
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,
Object[] parameters, Object[] arguments) at
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Python.Runtime.MethodBinder.Invoke(IntPtr inst, IntPtr args, IntPtr
kw, MethodBase info, MethodInfo[] methodinfo) at
Python.Runtime.MethodObject.Invoke(IntPtr target, IntPtr args, IntPtr
kw, MethodBase info) at Python.Runtime.MethodBinding.tp_call(IntPtr
ob, IntPtr args, IntPtr kw)
显然 IronPython 不允许我将自定义类型从 python 传递到 C#。为了解决这个问题,我在 C# 代码中添加了 Person
class:
public class Person
{
public Person(string name)
{
Name = name;
}
public string Name { get; set; }
}
然后我从 python 代码中删除了自定义 Person class 并引用了 C# 代码中的那个:
from ClassLibrary1 import Person
之后一切正常。
我想要一个 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<dynamic>
。但是,当 运行 >python MainApp.py
:
Traceback (most recent call last): File ".\MainApp.py", line 20, in result = myclass.SayHello(nameList) TypeError: No method matches given arguments for SayHello: (<type 'list'>)
我用下面的代码解决了:
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<dynamic>
更改为 dynamic[]
。
public string SayHello(dynamic[] names)
这修复了类型错误,但我开始收到一条新消息:
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Python.Runtime.Runtime.PyObject_GetAttrString(IntPtr pointer, String name) at Python.Runtime.PyObject.GetAttr(String name) at Python.Runtime.PyObject.TryGetMember(GetMemberBinder binder, Object& result) at CallSite.Target(Closure , CallSite , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at ClassLibrary1.Class1.SayHello(Object[] names) in C:\Projects\csharp-nine-cookbook\csharp-nine-cookbook\CSharp9Cookbook\ClassLibrary1\Class1.cs:line 11 --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Python.Runtime.MethodBinder.Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo) at Python.Runtime.MethodObject.Invoke(IntPtr target, IntPtr args, IntPtr kw, MethodBase info) at Python.Runtime.MethodBinding.tp_call(IntPtr ob, IntPtr args, IntPtr kw)
显然 IronPython 不允许我将自定义类型从 python 传递到 C#。为了解决这个问题,我在 C# 代码中添加了 Person
class:
public class Person
{
public Person(string name)
{
Name = name;
}
public string Name { get; set; }
}
然后我从 python 代码中删除了自定义 Person class 并引用了 C# 代码中的那个:
from ClassLibrary1 import Person
之后一切正常。