我正在尝试在Python中使用.NET dll。在.NET语言中,该方法需要通过引用传递2个数组,然后修改它:
public void GetItems(
out int[] itemIDs,
out string[] itemNames
)
如何使用Python for .NET模块在Python中使用此方法?
编辑:忘记提及这是在CPython而不是IronPython。
其他信息。 当我执行以下操作时:
itemIDs = []
itemNames = []
GetItems(itemIDs, itemNames)
我得到的输出如下:
(None, <System.Int32[] at 0x43466c0>, <System.String[] at 0x43461c0>)
我是否只需要弄清楚如何将这些转换回python类型?
答案 0 :(得分:7)
PythonNet并没有像IronPython那样清楚地记录这一点,但它几乎完全相同。
所以,让我们看一下ref
and out
parameters的IronPython文档:
Python语言按值传递所有参数。没有语法表明参数应该通过引用传递,就像通过ref和out关键字在.NET语言(如C#和VB.NET)中一样。 IronPython支持两种将ref或out参数传递给方法的方法,一种隐式方式和一种显式方式。
以隐式方式,参数通常传递给方法调用,并且从方法调用返回其(可能)更新的值以及正常返回值(如果有)。这很好地反映了多个返回值的Python特性......
以显式方式,您可以为ref或out参数传递
,那么显式方法很有用clr.Reference[T]
的实例,并且其值字段将由调用设置。如果有多个带参数的重载......
两者都有例子。但要根据您的具体情况进行定制:
itemIDs, itemNames = GetItems()
或者,如果你真的想要:
itemIDsRef = clr.Reference[Array[int]]()
itemNamesRef = clr.Reference[Array[String]]()
GetItems(itemIDs, itemNames)
itemIDs, itemNames = itemIDsRef.Value, itemNamesRef.Value
使用PythonNet的CPython基本上做同样的事情。执行out
参数的简单方法是不传递它们并接受它们作为额外的返回值,并且ref
参数将输入值作为参数传递并接受输出值作为额外的返回值。就像IronPython的隐式解决方案一样。 (除void
函数ref
或out
参数始终在None
或ref
参数之前返回out
之外,即使它不会&# 39;在IronPython中。)你可以通过检查返回值很容易地弄清楚它。所以,在你的情况下:
_, itemIDs, itemNames = GetItems()
与此同时,这些恰好是阵列的事实并没有让事情变得更难。正如the docs解释的那样,PythonNet为所有IEnumerable
集合提供了可迭代接口,为Array
提供了序列协议。所以,你可以这样做:
for itemID, itemName in zip(itemIDs, itemNames):
print itemID, itemName
Int32
和String
个对象将转换为原生int
/ long
和str
/ unicode
个对象,就好像它们一样直接归还。
如果您确实希望将这些显式转换为本机值,则可以。 map
或列表推导将为您提供任何可迭代的Python列表,包括围绕Array
或其他IEnumerable
的PythonNet包装器。如果需要,您可以明确地从long
或unicode
中制作Int32
或String
。所以:
itemIDs = map(int, itemIDs)
itemNames = map(unicode, itemNames)
但是我没有看到这样做的好处,除非您需要在使用任何值之前预先检查所有值。
答案 1 :(得分:1)
我设法使用了这个方法 来自C#库CyUSB.dll的bool XferData(ref byte [] buf,ref int len) 使用以下代码:
>>> xferLen = 2;
>>> outData=[10, 0]
>>> inData=[]
>>> n, outData, xferLen = XferData(outData, xferLen)
>>> print n, outData[0], outData[1], xferLen
True 10 0 2
希望这有助于某人。