11

好吧,我已经快要完成这个了,我可以尝尝。在过去的几周左右,我一直在尝试创建一个 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

问题出现在函数“回调”中,我得到错误:“无法将 '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 似乎正确地读取了数组等等,所以这个案例似乎已经结束。非常感谢。

4

2 回答 2

5
ctypedef unsigned short const_ushort "const uint16_t"

使const出现在 C 代码中,所以你得到typedef unsigned short const uint16_tconst是没有意义的。(它还重新定义了uint16_t不应该的标准类型。)

你可能会取得更大的成功

ctypedef unsigned short *ushort_p "ushort_p"

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

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

于 2011-03-11T15:42:04.907 回答
1

这不是您要问的,但是如果您想做的是在 Cython 中使用一组无符号短裤,然后让您的答案在 Python 端可访问,您可以在 Python 端创建一个 Numpy ndarray 并通过将它放入 Cython 中,它与多维数组大致相同。这样,您就可以同时获得 Python 的内存管理、一些方便的索引语法以及在 Cython 中处理真实数组的速度。

这是我的 Project Euler 解决方案中的一个示例

于 2011-03-11T16:33:34.563 回答