2014-06-13 113 views
0

我想用用Cython運行在python3環境中的C++庫。 當我試圖將int數組返回到蟒蛇是這樣的:轉換數組c到Python字節

def readBytes(self, length): 
    cdef int *buffer = [] 
    self.stream.read(buffer, length) 
    return buffer 

我得到的錯誤

return buffer 
       ^
Cannot convert 'int *' to Python object 

附:如果我使用

cdef char *buffer = '' 
+0

它看起來像stream.read()分配'buffer'指向的內存。如果是這樣的話,你不能返回到C++空間分配的python空間數據。 – gg349

+0

@flebool如何在char上工作? –

+0

見答案,太短留在這裏 – gg349

回答

0

char可以自動強制爲bytes,因爲用Cython認爲他們是大致相同的,可以做快我不明白的錯誤。請注意,char *指針將默認爲空終止。

這不是int *實現。您通常需要coerce to a Numpy object(這實際上是包裝數組)。如果你想要更快的東西,想想cpython.array

+0

不知道如何將這種(強迫到numpy的對象)適用於我的代碼,我已經試過了,它給我一個錯誤:指針基類型不匹配cython.array基本類型 –

+0

注意,簡單地強制數組將泄漏指向內存。只有當您計劃在本地(在cython中)使用數據並返回與數據本身不同的東西時,這纔是一個好主意。 – gg349

1

它看起來像stream.read()分配由buffer指向的內存。如果是這樣的話,你不能返回到C++空間分配的python空間數據。你應該:

1)創建一個Python對象,或numpy數組,如果你願意,在python /用Cython代碼

2)由*buffer指出,分配新的閃亮Python對象所分配的內存中的數據複製在python空間。然後你可以返回這個對象。

這是必要的,因爲python無法以任何方式處理在C空間中分配的內存,並且您的C代碼分配的內存正在泄漏,即它不會被釋放。

現在你還問,爲什麼你不cdef char *buffer = ''得到錯誤。在後一種情況下,cython識別出buffer指向一個字符串,並自動生成一個新的Python對象,其內容指向buffer。例如遵循ipython

%%cython 
def ReturnThisString(): 
    cdef char *buffer = 'foobar' 
    return buffer 

print ReturnThisString() #this outputs 'foobar' 

注意buffer由您C編譯器堆棧初始化,而且也沒有保證,當你從蟒蛇使用此函數的字符串將仍然存在於內存位置。但是,當cython運行return語句時,它會自動從你的char *指針初始化一個python字符串。 (在python 3中,我認爲它被轉換爲bytes @Veedrac說,但這是一個小問題)。在這第二種情況下,Python對象的創建和複製操作是隱藏的並由cython保留,但它仍然存在。