更新 GitHub 上的最小示例:https://github.com/wl2776/cython_error
我有一个 C 库,我想从 Python 访问它。我正在为它开发一个 Cython 包装器。
库有以下声明:
文件“globals.h”
typedef struct
{
int x;
int y;
int radius;
} circleData;
文件“O_Recognition.h”
#include "globals.h"
typedef struct
{
int obj_count;
circleData circle_data[2];
float parameters[2];
} objectData;
我将这些类型映射到 .pxd 文件中的 Cython,如下所示:
文件“cO_Recognition.pxd”:
cdef extern from "globals.h":
ctypedef struct circleData:
int x;
int y;
int radius;
cdef extern from "O_Recognition.h":
ctypedef struct objectData:
int obj_count;
circleData circle_data[2];
float parameters[2];
这不会编译。我收到错误:
Error compiling Cython file:
------------------------------------------------------------
...
void PyTuple_SET_ITEM(object p, Py_ssize_t pos, object o)
void PyList_SET_ITEM(object p, Py_ssize_t pos, object o)
@cname("__Pyx_carray_to_py_circleData")
cdef inline list __Pyx_carray_to_py_circleData(circleData *v, Py_ssize_t length):
^
------------------------------------------------------------
carray.to_py:112:45 'circleData' is not a type identifier
更详细一点,这是 CMake 项目的一部分,它是使用 GitHub 中的示例构建的:https://github.com/thewtex/cython-cmake-example
CMakeLists.txt 的相关部分包括具有其他名称的 .pyx 文件,cimport
s 这个 cDeclarations.pxd
最佳答案
问题是 circleData
在 O_Recognition.h
外部 block 中未定义。其先前的定义仅适用于 globals.h
外部 block 。
只需要包含它的类型,以便 Cython 知道它是什么。不需要重新定义。
cdef extern from "globals.h" nogil:
ctypedef struct circleData:
int x;
int y;
int radius;
cdef extern from "O_Recognition.h" nogil:
ctypedef struct circleData:
pass
ctypedef struct objectData:
int obj_count;
circleData circle_data[2];
float parameters[2];
编译代码时,.c
文件将包含
两个头文件并从globals.h
获取circleData 的类型定义.
从技术上讲,globals.h
extern block 中的 circleData
成员的定义也不需要除非结构成员将被使用在 Cython 代码中。
请记住,pxd
文件是 Cython 代码的定义,而不是 C 代码。只包含要在 Cython 代码中使用的成员,否则可以只定义类型 sans 成员每个 circleData
上面的每个识别外部 block 。
关于python - 将结构中的 C 结构数组映射到 Cython,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43143367/