加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

使用Cython将malloc的缓冲区从C转换为Python而无需复制?

发布时间:2020-12-16 07:30:11 所属栏目:百科 来源:网络整理
导读:在Cython中,假设我有一个C函数,它返回一个用malloc()分配的大缓冲区,并期望稍后用free()释放. 现在我需要将此缓冲区作为(字节)str对象传递给Python,它将获取它的所有权,并在str对象消失后调用free().这可能吗?怎么样? 解决方法 使用numpy查看 https://gist
在Cython中,假设我有一个C函数,它返回一个用malloc()分配的大缓冲区,并期望稍后用free()释放.

现在我需要将此缓冲区作为(字节)str对象传递给Python,它将获取它的所有权,并在str对象消失后调用free().这可能吗?怎么样?

解决方法

使用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]

注意方法__dealloc__,当对BuffWrap实例的所有引用消失并且它被垃圾收集时,它将释放指针所占用的内存.这种自动释放是将整个事物包装在一个类中的一个很好的理由.

我无法弄清楚如何使用返回的指针并将其用于比如bytearray的缓冲区.如果有人知道,我有兴趣看.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读