使用Cython将malloc的缓冲区从C转换为Python而无需复制? [英] Converting malloc'ed buffers from C to Python without copy using Cython?

查看:131
本文介绍了使用Cython将malloc的缓冲区从C转换为Python而无需复制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Cython中,说我有一个C函数,该函数返回分配有malloc()的大缓冲区,并希望稍后再通过free()释放。

In Cython, say I have a C function that returns a large buffer allocated with malloc() and expected to be freed later with free().

现在,我需要将此缓冲区作为(字节)str对象传递给Python,这将获取它的所有权,并在str对象消失后再调用free()。

Now I need to pass this buffer to Python as a (bytes) str object, which would acquire ownership of it, and call free() later when the str object goes away. Is this possible and how?

推荐答案

看看 https://gist.github.com/1249305 用于使用numpy的实现。

Have a look at https://gist.github.com/1249305 for a implementation using numpy.

如果不是numpy然后可以使用memoryview这样的事情起作用:

If numpy is not an option then something like this could work, using a 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 实例的引用都消失并且将其收集为垃圾时释放指针持有的内存。这种自动释放是将整个内容包装在一个类中的一个很好的理由。

Note the method __dealloc__ which will free the memory held by the pointer when all references to an instance of BuffWrap disappear and it gets garbage collected. This automatic deallocation is a good reason to wrap the whole thing in a class.

我不知道如何使用返回的指针并将其用于缓冲区一个字节数组。如果有人知道,我很想看看。

I couldn't figure out how one could use the returned pointer and use it for the buffer of, say, a bytearray. If someone knows, I'd be interested to see.

这篇关于使用Cython将malloc的缓冲区从C转换为Python而无需复制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆