Cython - 将指向数组的指针转换为Python对象

时间:2011-03-11 10:25:03

标签: python cython

好吧,我非常接近完成这个我可以品尝它。在过去几周左右的时间里,我一直在尝试创建一个Python扩展,以便通过Cython与用C ++编写的库进行交互。在这里和一些朋友的帮助下,我已经设法获得了98%的感觉。唯一剩下的就是这个:我不能为我的生活弄清楚如何将指向无符号短裤数组的指针变成python对象(最好是列表)。

一点背景,我试图与设置回调函数的库的一部分接口,我已经成功完成了这个:

global callbackfunc

ctypedef unsigned short const_ushort "const uint16_t"

ctypedef void (*Function1)(const_ushort *data, unsigned width, unsigned height)

cdef extern from "lib.hpp":
    void SetCallback(Function1)

cdef void cSetCallback(Function1 function):
    SetCallback(function)

cdef void callcallback(const_ushort *data, unsigned width, unsigned height):
    global callbackfunc
    callbackfunc(data,width,height)

cSetCallback(callcallback)

def PySetCallback(callbackFunc):
    global callbackfunc
    callbackfunc = callbackFunc

问题发生在函数“callcallback”中,我得到错误:“无法将'const_ushort *'转换为Python对象”。我第一次尝试这个是创建一个新的python列表,并循环以将数组的每个元素放入一个python列表,如下所示:

datalist = []
for i in range(width*height):
    datalist += data[i]

遗憾的是,在编译的cython代码中,我试图将类型定义为“const const unsigned short”,这显然是一个问题。

然后我尝试了这个:

datalist = []
for i in data:
    datalist += i

这给了我“C数组迭代需要已知的结束索引”。请注意,我对C / C ++知之甚少,因此大部分内容对我来说都没有多大意义。

所以,无论如何,是否有任何有效的方法将这样的指针转换为python对象(最好比循环遍历数组更快,因为它通常约为57344项,这对时间非常敏感)

修改: 稍微澄清一点,正如我所提到的,我正在使用回调,并且调用它的库中的C ++函数会发送一个指向“const uint_16”数组的指针,这就是我用这种方式定义const_ushort的原因,否则类型不统一。我无法以任何方式修改库。

EDIT2 : 看起来我明白了。我最终要做的是显式地将数组转换为无符号短路数组,而不是const无符号短路数组,我可以用非常数索引它们。为了实现这一点,我创建了另一个这样的C ++函数(其他人为我编写了它,我几乎不懂C ++):

unsigned short *convert_short(const unsigned short *test){ return const_cast<unsigned short *>(test); }

这使我能够在我的类中创建“ getindex ”函数,并根据函数返回正确的值。所以是的,Python似乎正在正确读取数组,所以这个案例似乎已经关闭了。非常感谢。

2 个答案:

答案 0 :(得分:4)

ctypedef unsigned short const_ushort "const uint16_t"

使const出现在C代码中,因此typedef unsigned short const uint16_t无效const。 (它还重新定义了它不应该的标准类型uint16_t。)

可能会取得更大的成功
ctypedef unsigned short *ushort_p "ushort_p"

出于某种原因,Cython似乎无法识别C const关键字。您可能必须在回调周围使用包装来处理const问题。

如果您希望将指针转换为Python对象,请将其包装在cdef class中。确保该类记录高度和宽度,因为这些不记录在C数组中。

答案 1 :(得分:1)

这不是你要求的,但是如果你想要做的是在Cython中使用一组unsigned short,然后在Python端可以访问你的答案,你可以在Python上创建一个Numpy ndarray然后将它传递给Cython,它与多维数组大致相同。这样,你就可以获得Python的内存管理,一些方便的索引语法,以及在Cython中使用真实数组的速度。

这是我的Project Euler解决方案中的an example

相关问题