Cython:外部结构定义抛出编译器错误

Cython: external struct definition throws compiler error

我正在尝试在 Cython 中使用 Collections-C

我注意到 .c 文件中定义了一些结构,并且它们的别名在 .h 文件中。当我尝试在 .pxd 文件中定义这些结构并在 .pyx 文件中使用它们时,gcc 抛出错误:storage size of ‘[...]’ isn’t known

我能够将我的问题重现为复制外部库和我的应用程序的最小设置:

testdef.c

/* Note: I can't change this */
struct bogus_s {
    int x;
    int y;
};

testdef.h

/* Note: I can't change this */
typedef struct bogus_s Bogus;

cytestdef.pxd

# This is my code
cdef extern from 'testdef.h':
    struct bogus_s:
        int x
        int y

    ctypedef bogus_s Bogus

cytestdef.pyx

# This is my code
def fn():
    cdef Bogus n

    n.x = 12
    n.y = 23

    print(n.x)

如果我 运行 cythonize,我得到

In function ‘__pyx_pf_7sandbox_9cytestdef_fn’:
cytestdef.c:1106:9: error: storage size of ‘__pyx_v_n’ isn’t known
Bogus __pyx_v_n;
      ^~~~~~~~~

如果我使用 Cython manual 中指示的 ctypedef Bogus: [...] 符号,我也会遇到同样的错误。

我做错了什么?

谢谢。

查看您的 Collections-C 库的文档,这些是您应该纯粹通过指针使用的不透明结构(不需要知道指针的大小,而您需要在堆)。这些结构的分配在库函数中完成。

要更改示例以匹配这种情况:

 // C file
 int bogus_s_new(struct bogus_s** v) {
     *v = malloc(sizeof(struct bogus_s));
     return (v!=NULL);
 }

 void free_bogus_s(struct bogus_s* v) {
      free(v);
 }

您的 H 文件将包含这些声明,而您的 pxd 文件将包含声明的包装器。然后在 Cython 中:

def fn():
    cdef Bogus* n
    if not bogus_s_new(&n):
        return
    try:
        # you CANNOT access x and y since the type is
        # designed to be opaque. Instead you should use
        # the acessor functions defined in the header
        # n.x = 12
        # n.y = 23
    finally:
        free_bogus_s(n)