将C数组转换为Python字节

时间:2014-06-13 14:07:07

标签: python c++ cython

我正在尝试使用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

P.S。如果我使用

,我不会收到错误
 cdef char *buffer = ''

2 个答案:

答案 0 :(得分:1)

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

1)如果你愿意,可以在python / cython代码中创建一个python对象或numpy数组

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所说,但这是一个小问题)。在第二种情况下,cython隐藏并创建了python对象和复制操作,但它仍然存在。

答案 1 :(得分:0)

char可以自动强制转换为bytes,因为Cython认为它们大致相同并可以快速完成。请注意,char *指针默认为空终止。

int *未实现此功能。您通常需要coerce to a Numpy object(这实际上是包装数组)。如果您想要更快,请考虑cpython.array