转换为指向Cython扩展类的指针

5

我是一名新手,刚开始接触Cython,请多包涵。我试图将一些数据转换为扩展类的指针。该类本质上是一个增强版的结构体。在我的.pxd文件中声明如下:

cdef class Field:

    cdef:
        np.float64_t u                   # x velocity
        np.float64_t v                   # y velocity
        np.float64_t w                   # z velocity

    cdef update(self)

当然,这是在 .pyx 文件中实现的。在我的驱动代码中,我有一个 np.float64_t 的 4 维数组。前三维表示 x、y 和 z。第四维应该表示这三个值 u, v, w。我在纯 Python 驱动程序中分配了网格,然后将网格传递给 Cython 文件。在 Cython 文件中,我进行了如下转换:

curr_grid_element = (<Field *> &grid[xx, yy, zz, 0])
curr_grid_element.update()

但是当我这样做时,我会收到错误:指向基类型不能是Python对象
这让我很困惑,因为我认为Field是纯C编写的。

Field 是一个 C 结构体,其中包含了您指定的字段 u、v 和 w,但它还包含了标准的 Python 引用计数机制。因此,您不能真正将一个 grid 数组重新解释为一个 Field,因为它不包含相同的引用计数字段。 - DavidW
1个回答

4
Cython的扩展类型extension types不会翻译成C结构,而是翻译成Python内置类型。从高层次来看,这意味着Field是一个Python类,它恰好是用C实现的,就像listndarray一样。在更低的层次上,Cython确实使用C结构来实现扩展类型,但这些结构具有您没有考虑到的字段。即用于跟踪其类型的字段和用于引用计数的另一个字段(可能还有其他字段)。

我认为你想要的是结构体,而不是扩展类型。请尝试以下内容:

cdef struct Field:
    np.float64_t u                   # x velocity
    np.float64_t v                   # y velocity
    np.float64_t w                   # z velocity

非常感谢。昨天经过一番思考,我得出了相同的结论。但是现在当我将一个Field *(即我的网格)传递给在.pyx文件中使用cdef定义的函数时,我会收到错误消息“无法将Field *转换为Python对象”。为什么它会将指向Field的指针转换为对象,而函数接受的是Field *?我现在正在使用手机,稍后可以发布代码。 - The Wind-Up Bird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接