我正在尝试在Cython中调用一个C函数,头文件如下:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <ctype.h>
#include <unistd.h>
#include <math.h>
#include <apriltag.h>
#include <tag36h11.h>
#include <common/getopt.h>
#include <common/image_u8.h>
#include <common/image_u8x4.h>
#include <common/pjpeg.h>
#include <common/zarray.h>
apriltag_detection_t* scan_frame(int width, int height, uint8_t* data);
如你所见,我想返回一个结构体数组,其中类型定义为
apriltag_detection_t
。根据文档,为了能在Cython中使用它,我必须定义一种类似于头文件的pxd
文件。然而,
apriltag_detection_t
是已经在apriltag.h
中定义的类型。此外,apriltag_detection_t
的成员已经在apriltag.h
中定义过了。在使用这个库之前,我需要递归地手动重新定义所有这些类型吗?我应该在哪里编写它们呢?谢谢!
更新6:
最终到了封装函数的步骤!
from libc.stdint cimport uint8_t
cdef extern from "<apriltag.h>":
cdef struct apriltag_detection:
int id
double c[2]
double p[4][2]
ctypedef apriltag_detection apriltag_detection_t
cdef extern from "tag36h11_detector/tag36h11_detector.h":
apriltag_detection_t* scan_frame(int width, int height, uint8_t* data);
def detect(width, height, frame):
return scan_frame(width, height, frame)
tag36h11_detector.pyx:15:21: 无法将'apriltag_detection_t *'转换为Python对象
apriltag_detection_t*
是一个结构体数组
更新5 这似乎已经解决了。
from libc.stdint cimport uint8_t
cdef extern from "<apriltag.h>":
cdef struct apriltag_detection:
int id
double c[2]
double p[4][2]
ctypedef apriltag_detection apriltag_detection_t
cdef extern from "tag36h11_detector/tag36h11_detector.h":
apriltag_detection_t* scan_frame(int width, int height, uint8_t* data);
更新 4 通过导入必要的类型解决了之前的问题。
from libc.stdint cimport uint8_t
cdef extern from "apriltag.h":
cdef struct apriltag_detection:
int id
double c[2]
double p[4][2]
ctypedef apriltag_detection apriltag_detection_t
cdef extern from "tag36h11_detector.h":
apriltag_detection_t* scan_frame(int width, int height, uint8_t* data);
tag36h11_detector.c:533:10: 致命错误:找不到'apriltag.h'文件
我不确定这是从哪里来的,因为我的头文件,正如原始帖子中提供的那样,需要<apriltag.h>
而不是"apriltag.h"
。这是我的setup.py
的样子。
from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules=cythonize(Extension(\
name='tag36h11_detector', \
sources=["tag36h11_detector.pyx", \
"tag36h11_detector/tag36h11_detector.c"], \
include_path=["/usr/local/include/apriltag"], \
libraries=["apriltag"])))
UPDATE 3
cdef extern from "apriltag.h":
cdef struct apriltag_detection:
int id
double c[2]
double p[4][2]
ctypedef apriltag_detection apriltag_detection_t
cdef extern from "tag36h11_detector.h":
apriltag_detection_t* scan_frame(int width, int height, uint8_t* data);
tag36h11_detector.pyx:10:60: 'uint8_t'不是类型标识符
更新2
以下是我的当前代码和编译错误
// tag36h11_detector.pyx
cdef extern from "apriltag.h":
ctypedef apriltag_detection_t:
int id
double c[2]
double p[4][2]
cdef extern from "tag36h11_detector.h":
apriltag_detection_t* scan_frame(int width, int height, uint8_t* data);
// apriltag.h
...
typedef struct apriltag_detector apriltag_detector_t;
...
tag36h11_detector.pyx:2:33: 在ctypedef语句中出现语法错误
更新1
所以我正在尝试使用在apriltag.h
(来自库)中定义的类型与上述头文件进行Python接口(我编写并实现了它)。
cdef extern from "apriltag.h":
struct apriltag_detection:
int id
double c[2]
double p[4][2]
cdef extern from "tag36h11_detector.h":
struct apriltag_detection* scan_frame(int width, int height, uint8_t* data);
尝试编译上述代码时,我遇到了以下错误:
ctypedef struct apriltag_detection
? - undefinedapriltag.h
中,struct
实际上是typedef struct apriltag_detection apriltag_detection_t
,所以我尝试考虑了这一点,但是我得到了一个不同的错误。 - undefinedapriltag_detection_t*
转换为 Python 对象"。这是一个结构体数组,所以我不确定如何编写合适的 Cython 代码。 - undefined