Преобразование буферов malloc из C в Python без копирования с использованием Cython?

В Cython, скажем, у меня есть функция C, которая возвращает большой буфер, выделенный с помощью malloc(), и ожидается, что он будет освобожден позже с помощью free().

Теперь мне нужно передать этот буфер в Python как объект str (bytes), который получит право собственности на него и вызовет free() позже, когда объект str исчезнет. Возможно ли это и как?


person Pol    schedule 23.04.2012    source источник


Ответы (1)


Посмотрите https://gist.github.com/1249305 для реализации с использованием numpy.

Если numpy не подходит, то что-то вроде этого может работать с использованием памяти:

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]

Обратите внимание на метод __dealloc__, который освобождает память, удерживаемую указателем, когда все ссылки на экземпляр BuffWrap исчезают и происходит сборка мусора. Это автоматическое освобождение — хорошая причина обернуть все это в класс.

Я не мог понять, как можно использовать возвращенный указатель и использовать его для буфера, скажем, массива байтов. Если кто знает, было бы интересно посмотреть.

person Mauro    schedule 19.05.2012