将C数组转换为Python字节

Converting C array to Python bytes

本文关键字:Python 字节 转换 数组      更新时间:2023-10-16

我试图使用Cython在python3环境中运行c++库。当我尝试像这样将int数组返回给python时:

def readBytes(self, length):
    cdef int *buffer = []
    self.stream.read(buffer, length)
    return buffer 

我得到错误

    return buffer
                ^
Cannot convert 'int *' to Python object

注:使用

不会出现错误
 cdef char *buffer = ''

看起来stream.read()分配了由buffer指向的内存。如果是这种情况,则无法返回在c++空间中分配的python空间数据。你应该:

1)创建一个python对象,或者一个numpy数组,如果你喜欢,在python/cython代码

2)将*buffer所指向的已分配内存中的数据复制到在python空间中分配的新闪亮python对象。然后你可以返回这个对象。

这是必要的,因为python不能以任何方式处理在C空间中分配的内存,并且C代码分配的内存是泄漏的,即它不会被释放。

现在你还问为什么你没有得到cdef char *buffer = ''的错误。在后一种情况下,cython识别出buffer指向一个字符串,并自动生成一个新的python对象,其内容由buffer指向。ipython的示例如下:

%%cython
def ReturnThisString():
    cdef char *buffer = 'foobar'
    return buffer
print ReturnThisString() #this outputs 'foobar'

注意buffer是由你的C编译器在堆栈上初始化的,并且不能保证当你从python中使用这个函数时,字符串仍然在那个内存位置。但是,当cython运行return语句时,它会自动从char *指针初始化一个python字符串。(在python 3中,我猜它被转换为bytes,如@Veedrac所说,但这是一个小问题)。在第二种情况下,python对象的创建和复制操作是隐藏的,并由cython负责,但它仍然存在。

char可以自动强制为bytes,因为Cython认为它们大致相同并且可以快速完成。注意,默认情况下,char *指针将以空结束。

这在int *中没有实现。您通常希望强制转换为Numpy对象(这实际上是封装数组)。如果你想要更快的东西,想想cpython.array