2012-04-23 5 views
4

Cythonでは、malloc()で割り当てられた大きなバッファを返すC関数があり、後でfree()で解放されると想定しています。Cythonを使用してコピーせずにmallocされたバッファをCからPythonに変換しますか?

このバッファをPythonに(バイト)strオブジェクトとして渡す必要があります。これは所有権を取得し、strオブジェクトがなくなるとfree()を呼び出します。これは可能ですか?

答えて

2

numpyを使用して実装する場合は、https://gist.github.com/1249305をご覧ください。

numpyのがオプションでない場合、このようなものがmemoryviewを使用して、仕事ができるが:

from libc.stdlib cimport free 
cimport fn # in here is the c function with signature: char * char_ret(int n); 

cdef class BuffWrap: 
    cdef long siz 
    cdef char * _buf 
    cdef char[:] arr 
    def __cinit__(self, long siz): 
     self.siz = siz 
     self._buf = fn.char_ret(siz) # storing the pointer so it can be freed 
     self.arr = <char[:siz]>self._buf 
    def __dealloc__(self): 
     free(self._buf) 
     self.arr = None 
    # here some extras: 
    def __str__(self): 
     if self.siz<11: 
      return 'BuffWrap: ' + str([ii for ii in self.arr]) 
     else: 
      return ('BuffWrap: ' + str([self.arr[ii] for ii in range(5)])[0:-1] + ' ... ' 
        + str([self.arr[ii] for ii in range(self.siz-5, self.siz)])[1:]) 
    def __getitem__(self, ind): 
     """ As example of magic method. Implement rest of to get slicing 
     http://docs.cython.org/src/userguide/special_methods.html#sequences-and-mappings 
     """ 
     return self.arr[ind] 

BuffWrapのインスタンスへのすべての参照が消えたときにポインタが保持しているメモリを解放する方法__dealloc__それはガベージコレクションされます。この自動割り当て解除は、クラス内のすべてを包む良い理由です。

返されたポインタをどのように使用して、たとえばbytearrayのバッファに使用するかわかりませんでした。誰かが知っているなら、私は見たいと思うだろう。

関連する問題