如何使用在Python中修改的.NET方法?

时间:2013-10-25 22:23:00

标签: python .net pass-by-reference python.net

我正在尝试在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类型?

2 个答案:

答案 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函数refout参数始终在Noneref参数之前返回out之外,即使它不会&# 39;在IronPython中。)你可以通过检查返回值很容易地弄清楚它。所以,在你的情况下:

_, itemIDs, itemNames = GetItems()

与此同时,这些恰好是阵列的事实并没有让事情变得更难。正如the docs解释的那样,PythonNet为所有IEnumerable集合提供了可迭代接口,为Array提供了序列协议。所以,你可以这样做:

for itemID, itemName in zip(itemIDs, itemNames):
    print itemID, itemName

Int32String个对象将转换为原生int / longstr / unicode个对象,就好像它们一样直接归还。


如果您确实希望将这些显式转换为本机值,则可以。 map或列表推导将为您提供任何可迭代的Python列表,包括围绕Array或其他IEnumerable的PythonNet包装器。如果需要,您可以明确地从longunicode中制作Int32String。所以:

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

希望这有助于某人。