在 Cython 的结构中使用指针数组

Posted

技术标签:

【中文标题】在 Cython 的结构中使用指针数组【英文标题】:Using a pointer array within a struct in Cython 【发布时间】:2014-09-12 16:06:05 【问题描述】:

我正在尝试围绕 C 库编写 Cython 包装器。我对 Cython 很陌生,所以如果问题很明显,我提前道歉。

在文件 wrapper.pxd 中,我定义了一个结构(简化示例):

cdef extern from "thiscouldbeyourlibrary.h":
    cdef struct foo:
        double **output

然后我有课:

cdef class Bar:
    cdef wrapper.foo __stuff

    cdef do_something(self):
        self.__stuff.output = NULL

这失败了:

无法将 'void *' 转换为 Python 对象。

显然,Cython 不能确定 self.__stuff.output 始终是一个指针。但是我声明了它的类型并且这个类是一个“cdef”类,所以我真的不明白为什么。

【问题讨论】:

请注意,对于生成 Python 包装器的特定任务,有更好的工具,例如 SWIG(这就是 pywin32 使用的)。 @ivan_pozdeev 我知道。实际上已经有一个基于 SWIG 的我需要的特定库的包装器。但是,我遇到了一些问题(我所说的“问题”是指段错误),并且它并不能完全满足我的要求(NumPy 互操作性)。 只是猜测:使用None 而不是NULL - 这看起来更像是一个“Python 对象”:^) @EyPandaBear 你检查下面的答案了吗? 【参考方案1】:

问题是NULLdouble ** 之间的不兼容。您可以将其分配给charintvoid *,例如,这样做:

包装器.pyd:

cdef extern from "thiscouldbeyourlibrary.h":
    cdef struct foo:
        char a
        int b
        void *c
        double **output

这可能是你的图书馆.h:

struct foo
 
    char a;
    int b;
    void *c;
    double **output;
;

main.pyx:

cimport wrapper

cdef class Bar:
    cdef wrapper.foo __stuff
    def __init__(self):
        self.__stuff.a = <char>NULL
        self.__stuff.b = <int>NULL
        self.__stuff.c = NULL

def main():
    bar = Bar()
    print bar.__stuff.a
    print bar.__stuff.b

如果您之前为output 分配了内存,您可以这样做:

self.__stuff.output[0] = NULL

不分配就会崩溃...

【讨论】:

以上是关于在 Cython 的结构中使用指针数组的主要内容,如果未能解决你的问题,请参考以下文章

C ++在指向结构的指针中访问类数组指针

C++结构体指针数组如何分配空间,用new

从指向结构数组的指针中提取元素

程序的错误输出,使用指向结构数组的指针

结构体指针数组和结构体数组指针的区别

使用指向结构数组的指针不会返回完整的数组