我试图使用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
。