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

3
我将尝试编写一个Cython包装器,以便使用C库。对于Cython,我还是个新手,如果问题很明显,请提前谅解。
在wrapper.pxd文件中,我定义了一个结构体(简化示例):
cdef extern from "thiscouldbeyourlibrary.h":
    cdef struct foo:
        double **output

I then have a class:

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
@ivan_pozdeev 我知道。实际上,我需要的特定库已经有一个基于SWIG的包装器了。然而,我在使用它时遇到了一些问题(我的意思是段错误),而且它并没有完全满足我想要的(NumPy互操作性)。 - EyPandaBear
只是猜测:使用 None 而不是 NULL - 这看起来更像一个“Python对象” :^) - ivan_pozdeev
@EyPandaBear 你有没有检查下面的答案? - Saullo G. P. Castro
1个回答

1
问题在于NULLdouble **之间的不兼容性。例如,您可以将其分配给charintvoid *

wrapper.pyd:

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

thiscouldbeyourlibrary.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

没有分配内存,程序会崩溃...


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