我有一个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填充。如果返回的数组大于填充数组元素后结果被截断。
如果有帮助,返回数组的结构包含返回数组的大小作为其第一个元素。
先谢谢你的帮助......
答案 0 :(得分:4)
通常最好让调用者分配缓冲区。这样调用者也可以解除分配。但是,在这种情况下,只有被调用者知道缓冲区需要多长时间。因此,onus传递给被调用者以分配缓冲区。
但是这给系统带来了额外的限制。由于被调用者正在分配缓冲区,因此除非它们共享相同的分配器,否则调用者不能解除分配。实际上可以毫无困难地安排。您可以使用共享分配器。有几个。您的平台似乎是Windows,因此您可以使用CoTaskMemAlloc
和CoTaskMemFree
。接口的两端都可以调用这些功能。
另一种方法是将分配和解除分配保持在一起。调用者必须保持被调用者返回的指针。当它完成缓冲区后,通常在将其复制到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