在 Cython 中,假设我有一个 C 函数,它返回一个用 malloc() 分配的大缓冲区,并预计稍后会用 free() 释放。
现在我需要将此缓冲区作为(字节)str 对象传递给 Python,该对象将获得它的所有权,并在 str 对象消失后调用 free()。这可能吗?如何?
在 Cython 中,假设我有一个 C 函数,它返回一个用 malloc() 分配的大缓冲区,并预计稍后会用 free() 释放。
现在我需要将此缓冲区作为(字节)str 对象传递给 Python,该对象将获得它的所有权,并在 str 对象消失后调用 free()。这可能吗?如何?
查看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
这种自动释放是将整个事物包装在一个类中的一个很好的理由。
我不知道如何使用返回的指针并将其用于字节数组的缓冲区。如果有人知道,我很想看看。