2013-04-15 79 views
2

我有一個C++函數,它接受指向已知大小數組的指針作爲輸入,並返回一個大小數組,直到函數完成其數據處理才能確定大小數組。我如何調用C++函數,傳遞第一個數組並接收第二個數組的結果?ctypes 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

*「如果它比較小,那麼數組的空元素將填充0」。*這純粹是基於內存是否被分配和歸零。它可以像段錯誤一樣簡單。 ctypes不會將返回數組複製到新的緩衝區中。 – eryksun

回答

4

通常最好是讓來電者分配的緩衝區。這樣調用者也可以釋放它。但是,在這種情況下,只有被調用者知道緩衝區需要多長時間。所以責任傳遞給被調用者來分配緩衝區。

但是這給系統帶來了額外的限制。由於被調用者正在分配緩衝區,因此調用者不能釋放它,除非它們共享相同的分配器。這實際上可以安排,沒有太多的麻煩。您可以使用共享分配器。有幾個。您的平臺似乎是Windows,因此您可以使用CoTaskMemAllocCoTaskMemFree。界面的兩側都可以調用這些函數。

另一種方法是保持分配和釋放在一起。調用者必須堅持被調用者返回的指針。當它完成緩衝區時,通常在將其複製到Python結構後,它會要求庫釋放內存。

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