5

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

4

2 回答 2

8

PythonNet 没有像 IronPython 那样清楚地记录这一点,但它几乎做了同样的事情。

因此,让我们看一下 IronPython 文档refout参数

Python 语言按值传递所有参数。没有语法表明参数应该通过引用传递,就像在 .NET 语言(如 C# 和 VB.NET)中通过 ref 和 out 关键字。IronPython 支持将 ref 或 out 参数传递给方法的两种方式,隐式方式和显式方式。

在隐式方式中,参数通常被传递给方法调用,并且其(可能)更新的值与正常的返回值(如果有)一起从方法调用返回。这与 Python 的多返回值特性很好地组合在一起……</p>

以显式方式,您可以为 ref 或 out 参数传递一个实例clr.Reference[T],其 Value 字段将由调用设置。如果有多个带有 ref 参数的重载,则显式方法很有用……</p>

两者都有例子。但要根据您的具体情况定制它:

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带有reforout参数的函数总是在or参数None之前返回,即使它不会在 IronPython 中。)您可以通过检查返回值很容易地找出它。所以,在你的情况下:refout

_, itemIDs, itemNames = GetItems()

同时,这些恰好是数组的事实并没有使事情变得更难。正如文档解释的那样,PythonNet 为所有IEnumerable集合提供了可迭代接口,并为Array. 所以,你可以这样做:

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

并且Int32andString对象将被转换为原生的int/longstr/unicode对象,就像它们被直接返回一样。


如果您真的想将这些显式转换为本机值,您可以。map或者列表推导式将为您提供来自任何可迭代的 Python 列表,包括围绕 anArray或 other的 PythonNet 包装器IEnumerable。如果需要,您可以明确地制作 alongunicodeout 。所以:Int32String

itemIDs = map(int, itemIDs)
itemNames = map(unicode, itemNames)

但我认为这样做并没有多大优势,除非您需要,例如,在使用任何值之前预先检查所有值。

于 2013-10-25T22:26:35.850 回答
2

I have managed to use the method bool XferData(ref byte[] buf, ref int len) from C# library CyUSB.dll with the following code:

>>> xferLen = 2;

>>> outData=[10, 0]

>>> inData=[]

>>> n, outData, xferLen = XferData(outData, xferLen)

>>> print n, outData[0], outData[1], xferLen

True 10 0 2

Hope this helps someone.

于 2014-12-16T16:38:08.530 回答