ctypes c ++函数返回未知大小的数组

时间:2013-04-15 19:50:08

标签: c++ python arrays ctypes

我有一个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填充。如果返回的数组大于填充数组元素后结果被截断。

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

先谢谢你的帮助......

2 个答案:

答案 0 :(得分:4)

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

但是这给系统带来了额外的限制。由于被调用者正在分配缓冲区,因此除非它们共享相同的分配器,否则调用者不能解除分配。实际上可以毫无困难地安排。您可以使用共享分配器。有几个。您的平台似乎是Windows,因此您可以使用CoTaskMemAllocCoTaskMemFree。接口的两端都可以调用这些功能。

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

答案 1 :(得分:1)

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