3

I have a cdefed class in Cython which looks very similar to this:

cdef class AprilTagDetector:
    cdef capriltag.apriltag_detector_t* _apriltag_detector

    def __cinit__(self):
        self._apriltag_detector = capriltag.apriltag_detector_create();
        # standard null checks
    # standard __dealloc__(self) here

    property quad_decimate:
        def __get__(self):
            return self._apriltag_detector.quad_decimate

The corresponding .pxd file looks like this:

cdef extern from "apriltag.h":
    # The detector itself
    ctypedef struct apriltag_detector_t:
        pass

    # Detector constructor and destructor
    apriltag_detector_t* apriltag_detector_create()
    void apriltag_detector_destroy(apriltag_detector_t* td);

The problem is, when I go to compile this code, it spits out this error:

property quad_decimate:
    def __get__(self):
        return self._apriltag_detector.quad_decimate             ^
------------------------------------------------------------

apriltags.pyx:47:14: Cannot convert 'apriltag_detector_t *' to Python object

What's going on here? I haven't been able to figure it out from the Cython docs.

Liam Marshall
  • 1,353
  • 1
  • 12
  • 21

1 Answers1

1

I, thankfully, figured out the problem when working on this project with a friend at a hackerspace. The problem is in the ctypedef struct apriltag_detector_t block. When I wrote pass in the block, I thought that Cython would automatically work out the internal contents of the struct, and let me access the element(s) I needed - here, quad_decimate.

Not so. To get Cython to understand the contents of a struct, you will have to tell it what's in the struct as so:

ctypedef struct apriltag_detector_t:
    float quad_decimate
Liam Marshall
  • 1,353
  • 1
  • 12
  • 21