Python for .NET:将 List<dynamic> 传递给 C# 函数
Python for .NET: passing List<dynamic> to C# function
我正在尝试从使用 Python for .NET 的 dll 从 python 代码调用 C# 函数。大多数事情都是开箱即用的,或者我可以从其他帖子中找出它们(比如从下面的数组传递一个 IntPtr),但最后拒绝工作的是传递一个列表作为参数。
这是 C# 函数
bool CalculateResult(string resultName, IntPtr resultArray, IList <dynamic> AuxParameters = null)
及其在示例 C# 代码片段中的使用方式:
CalculateResult("xyz", ptr, new List<dynamic> { 50 });
我确实成功地从 python 调用了函数,没有可选的第三个参数:
clr.AddReference('SDK')
import SDK_Namespace
from System import Array, Int16, IntPtr, String
from System.Runtime.InteropServices import GCHandle, GCHandleType
pyArr = [0] * 100
csArr = Array[Int16](pyArr )
arr_hndl = GCHandle.Alloc(csArr, GCHandleType.Pinned)
ptr_arr = arr_hndl.AddrOfPinnedObject()
CalculateResult(result, ptr_arr)
# pyArr has now values, yay!
现在,如果我尝试使用附加列表参数执行相同的操作,我将失败:
from System.Collections.Generic import List
pyList = [50]
CalculateResult(result, ptr_arr, pyList)
# TypeError: No method matches given arguments for CalculateResult
CalculateResult.__overloads__[String, IntPtr, List](result, ptr_arr, pyList)
# TypeError: No match found for signature
csList = List[Int16]()
csList.Add(50)
CalculateResult(result, ptr_arr, csList)
# TypeError: No method matches given arguments for CalculateResult
CalculateResult.__overloads__[String, IntPtr, List](result, ptr_arr, csList)
# TypeError: No match found for signature
我错过了什么,我怎样才能让它发挥作用?
编辑
根据 Jeroen 的评论并阅读 boxing and unboxing 我能够 运行 C# 函数如下:
from System import Object
par = int(50)
csList = List[Object]()
csList.Add(Object(par))
CalculateResult(result, ptr_arr, csList)
现在函数抛出异常,没有太多调试提示。
然而,另一个具有类似参数的函数 GetInfo(string resultName, IList <dynamic> AuxParameters = null)
告诉我更有帮助:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type
'object' to 'int'. An explicit conversion exists (are you missing a cast?)
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at SDK.GetInfo(String ResultName, IList`1 Parameters)
由于我无法在 C# 方面更改任何我怀疑必须发生拆箱的问题,因此问题更改为:
我还可以做些什么来执行 'explicit conversion' 还是我必须放弃?
不确定这是否适用于您的情况,但我能够在 Python 中使用它进行调用(使用 Python for .NET 扩展名):
xl = List[Object]()
xl.Add(50)
b = d.CalculateResult("resultName", ptr_arr, xl)
C# 方法中显示的对象属于 Int32
类型,这可能是预期的。
我实现了一个和你签名一样的测试方法,我用的是这个:
public bool CalculateResult(string resultName, IntPtr resultArray, IList<dynamic> AuxParameters = null)
{
if (AuxParameters != null)
{
dynamic a = AuxParameters.First();
Console.WriteLine(" *Type: " + ((object)a).GetType().Name);
foreach (var m in ((object)a).GetType().GetMembers())
{
Console.WriteLine(" " + m.Name);
}
Console.WriteLine(a);
}
return true;
}
我正在尝试从使用 Python for .NET 的 dll 从 python 代码调用 C# 函数。大多数事情都是开箱即用的,或者我可以从其他帖子中找出它们(比如从下面的数组传递一个 IntPtr),但最后拒绝工作的是传递一个列表作为参数。
这是 C# 函数
bool CalculateResult(string resultName, IntPtr resultArray, IList <dynamic> AuxParameters = null)
及其在示例 C# 代码片段中的使用方式:
CalculateResult("xyz", ptr, new List<dynamic> { 50 });
我确实成功地从 python 调用了函数,没有可选的第三个参数:
clr.AddReference('SDK')
import SDK_Namespace
from System import Array, Int16, IntPtr, String
from System.Runtime.InteropServices import GCHandle, GCHandleType
pyArr = [0] * 100
csArr = Array[Int16](pyArr )
arr_hndl = GCHandle.Alloc(csArr, GCHandleType.Pinned)
ptr_arr = arr_hndl.AddrOfPinnedObject()
CalculateResult(result, ptr_arr)
# pyArr has now values, yay!
现在,如果我尝试使用附加列表参数执行相同的操作,我将失败:
from System.Collections.Generic import List
pyList = [50]
CalculateResult(result, ptr_arr, pyList)
# TypeError: No method matches given arguments for CalculateResult
CalculateResult.__overloads__[String, IntPtr, List](result, ptr_arr, pyList)
# TypeError: No match found for signature
csList = List[Int16]()
csList.Add(50)
CalculateResult(result, ptr_arr, csList)
# TypeError: No method matches given arguments for CalculateResult
CalculateResult.__overloads__[String, IntPtr, List](result, ptr_arr, csList)
# TypeError: No match found for signature
我错过了什么,我怎样才能让它发挥作用?
编辑
根据 Jeroen 的评论并阅读 boxing and unboxing 我能够 运行 C# 函数如下:
from System import Object
par = int(50)
csList = List[Object]()
csList.Add(Object(par))
CalculateResult(result, ptr_arr, csList)
现在函数抛出异常,没有太多调试提示。
然而,另一个具有类似参数的函数 GetInfo(string resultName, IList <dynamic> AuxParameters = null)
告诉我更有帮助:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type
'object' to 'int'. An explicit conversion exists (are you missing a cast?)
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
at SDK.GetInfo(String ResultName, IList`1 Parameters)
由于我无法在 C# 方面更改任何我怀疑必须发生拆箱的问题,因此问题更改为:
我还可以做些什么来执行 'explicit conversion' 还是我必须放弃?
不确定这是否适用于您的情况,但我能够在 Python 中使用它进行调用(使用 Python for .NET 扩展名):
xl = List[Object]()
xl.Add(50)
b = d.CalculateResult("resultName", ptr_arr, xl)
C# 方法中显示的对象属于 Int32
类型,这可能是预期的。
我实现了一个和你签名一样的测试方法,我用的是这个:
public bool CalculateResult(string resultName, IntPtr resultArray, IList<dynamic> AuxParameters = null)
{
if (AuxParameters != null)
{
dynamic a = AuxParameters.First();
Console.WriteLine(" *Type: " + ((object)a).GetType().Name);
foreach (var m in ((object)a).GetType().GetMembers())
{
Console.WriteLine(" " + m.Name);
}
Console.WriteLine(a);
}
return true;
}