2

我有一个 c++ 函数,它接受一个指向已知大小数组的指针作为输入,并返回一个大小数组,该数组的大小在函数完成数据处理之前无法确定。如何调用 c++ 函数,传递第一个数组并将结果作为第二个数组接收?

我目前正在做类似的事情:

PYTHON:

def callout(largeListUlonglongs):
    cFunc = PyDLL("./cFunction.dll").processNumbers

    arrayOfNums = c_ulonglong * len(largeListUlonglongs)
    numsArray = arrayOfNums()

    for x in xrange(len(largeListUlonglongs)):
        numsArray[x] = long(largeListUlonglongs[x])

    cFunc.restype = POINTER(c_ulonglong * len(largeListUlonglongs))

    returnArray = cFunc(byref(numsArray)).contents

    return returnArray

只要 returnArray 的大小与 numsArray 相同,此方法就可以工作。如果它更小,则数组的空元素用 0 填充。如果返回的数组大于数组元素填充后的结果将被截断。

如果有帮助,返回数组的结构包含返回数组的大小作为其第一个元素。

我在这里先向您的帮助表示感谢...

4

2 回答 2

3

通常最好让调用者分配缓冲区。这样,调用者也可以释放它。但是,在这种情况下,只有被调用者知道缓冲区需要多长时间。因此,责任传递给被调用者来分配缓冲区。

但这对系统施加了额外的限制。由于被调用者正在分配缓冲区,因此调用者无法释放它,除非它们共享相同的分配器。这实际上可以安排,没有太多麻烦。您可以使用共享分配器。有几个。您的平台似乎是 Windows,因此例如您可以使用CoTaskMemAllocCoTaskMemFree. 接口的两边都可以调用这些函数。

另一种方法是将分配和释放保持在一起。调用者必须持有被调用者返回的指针。当它完成缓冲区时,通常是在将其复制到 Python 结构中之后,它会要求库释放内存。

于 2013-04-15T19:58:35.400 回答
2

David 就内存管理问题为您提供了有用的建议。我通常会使用更简单的策略,即在库中有一个函数来释放分配的缓冲区。调用者有责任防止内存泄漏。

对我来说,您的问题似乎只是将结果转换为正确的指针类型。由于索引中的长度为 0,因此可以将结果类型设置为long long指针。然后获取大小,以便您可以将结果转换为正确的指针类型。

def callout(largeListUlonglongs):
    cFunc = PyDLL("./cFunction.dll").processNumbers
    cFunc.restype = POINTER(c_ulonglong)

    arrayOfNums = c_ulonglong * len(largeListUlonglongs)
    numsArray = arrayOfNums(*largeListUlonglongs)   

    result = cFunc(numsArray)
    size = result[0]
    returnArray = cast(result, POINTER(c_ulonglong * size))[0]

    return returnArray
于 2013-04-16T05:10:47.663 回答