【发布时间】:2018-03-12 22:48:16
【问题描述】:
我正在尝试在 Cython 中返回一个结构数组。
// .pyx
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);
cdef class Detection:
# how do I "link" this to the struct defined above?
def __cinit__(self):
pass
def __dealloc__(self):
pass
def detect(width, height, frame):
return scan_frame(width, height, frame)
理想情况下,我想在 Python 代码中调用 detect 函数,并获取 Detection 对象列表,其中 Detection 是 C 结构 apriltag_detection 的包装类,它的类型定义为 @ 987654328@.
我收到以下编译错误:
tag36h11_detector.pyx:22:21: 无法将 'apriltag_detection_t *' 转换为 Python 对象
我在文档中的任何地方都找不到返回指向结构或结构数组的指针的引用。
更新 3
// .h
typedef struct detection_payload {
int size;
apriltag_detection_t** detections;
} detection_payload_t;
我正在尝试将上述结构转换为包含 size 的 Python 对象和包含 apriltag_detection_t 对象的 Python 列表。
// .pyx
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":
cdef struct detection_payload:
int size
apriltag_detection_t** detections
ctypedef detection_payload detection_payload_t
detection_payload* scan_frame(int width, int height, uint8_t* data)
...
cdef class Detection:
cdef apriltag_detection* _d
def __cinit__(self):
self._d = NULL
cdef _setup(self, apriltag_detection* d):
self._d = d
def __dealloc__(self):
self._d = NULL
property id:
def __get__(self):
return self._d.id
property c:
def __get__(self):
return self._d.c
property p:
def __get__(self):
return self._d.p
cdef Detection_create(apriltag_detection_t* d):
return Detection()._setup(d)
cdef class DetectionPayload:
cdef detection_payload* _p
def __cinit__(self):
self._p = NULL
cdef _setup(self, detection_payload* p):
self._p = p
self.size = p.size
self.detections = []
for i in range(0, self.size):
apriltag_detection_t* detection = self._p.detections[i]
d = Detection_create(detection)
self.detections+=[d]
def __dealloc__(self):
_p = NULL
property size:
def __get__(self):
return self.size
property detections:
def __get__(self):
return self.detections
我遇到了几个语法错误:
apriltag_detection_t* detection = self._p.detections[I]
具体来说,在指针apriltag_detection_t*上
更新 2
现在可以正常编译和导入。数组仍然没有进展
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);
cdef class Detection:
cdef apriltag_detection* _d
def __cinit__(self):
self._d = NULL
cdef _setup(self, apriltag_detection* d):
self._d = d
def __dealloc__(self):
self._d = NULL
property id:
def __get__(self):
return self._d.id
property c:
def __get__(self):
return self._d.c
property p:
def __get__(self):
return self._d.p
cdef Detection_create(apriltag_detection_t* d):
return Detection()._setup(d)
def detect(width, height, frame):
cdef apriltag_detection_t* detection = scan_frame(width, height, frame)
return Detection_create(detection)
更新 1
我尝试按照下面链接的帖子进行操作,这就是我目前所拥有的。
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);
cdef class Detection:
cdef apriltag_detection* _d;
def __cinit__(self):
self._d = NULL
def _setup(self, apriltag_detection* d):
self._d = d
def __dealloc__(self):
self._d = NULL
property id:
def __get__(self):
return self._t.id
property c:
def __get__(self):
return self._t.c
property p:
def __get__(self):
return self._t.p
cdef Detection_create(apriltag_detection_t* d):
return Detection()._setup(d)
def detect(width, height, frame):
return <Detection>scan_frame(width, height, frame)
虽然这比我以前更接近,但我仍然收到错误:
tag36h11_detector.pyx:33:30: 无法将 'apriltag_detection_t *' 转换为 Python 对象
上线
cdef Detection_create(apriltag_detection_t* d):
return Detection()._setup(d)
此外,我不知道如何返回 Python 列表...
【问题讨论】:
-
这非常接近重复的stackoverflow.com/questions/23545875/…。它是关于单个结构而不是数组,但想法非常接近
-
@DavidW 谢谢你,但使用他们的代码会导致同样的错误。我也不知道如何返回 Python 列表...
-
不是您当前问题的解决方案,而是下一个问题的解决方案;)因为'frame'不是指针cython.readthedocs.io/en/latest/src/tutorial/array.html
-
顺便说一句,如果scan_frame返回一个数组,你怎么知道数组中有多少个标签?
-
@ead 啊..我不知道!也许我应该返回一个包含大小并指向
apriltag_detection_ts 数组的结构?
标签: python c arrays struct cython