简体   繁体   中英

How to write cython wrapper for a C++ function that returns a tuple of enums?

I have a C++ class looks like below:

// FILE client_matcher.hpp

class DcmSMR {
 public:
  DcmSMR(int64 t, int32_t o, int32_t l) : ts64(t), moffset(o), mlength(l) {}
  DcmSMR() : DcmSMR(0, -1, 0) {}

 public:
  int64_t ts64;
  int32_t moffset;
  int32_t mlength;
};

enum class CmResult { Unknown = 0, Detected, Continued };
enum class CmEvent { NotRaised = 0, Raised };

class ClientMatcher {
 public:
  std::tuple<CmResult, CmEvent> do_track(const DcmSMR& smr) {
    return {CmResult::Unknown, CmEvent::NotRaised};
  }
};

And some cython wrapper for it:

// FILE CmPy.pyx

cdef extern from "client_matcher.hpp" nogil:
    cdef cppclass DcmSMR:
        DcmSMR()
        DcmSMR(cint.int64_t t, cint.int32_t o, cint.int32_t l)

    enum CmResult:
        cm_Unknown "CmResult::Unknown"
        cm_Detected "CmResult::Detected"
        cm_Continued "CmResult::Continued"

    enum CmEvent:
        cm_NotRaised "CmEvent::NotRaised"
        cm_Raised "CmEvent::Raised"

    cdef cppclass ClientMatcher "ClientMatcher":
        ClientMatcher()
        (CmResult, CmEvent) do_track(DcmSMR& smr)

cdef class CmPy:
    cdef:
        ClientMatcher* cm_inst
        bool inited

    def __cinit__(self):
        self.inited = False

    def __dealloc__(self):
        self.inited = False
        self.cm_inst = NULL

    property inited:
        def __get__(self):
            return self.inited

    cpdef void init(self):
        self.cm_inst = new ClientMatcher()
        self.inited = True

    cpdef tuple do_track(self, cint.uint64_t t, int o, int l):
        cdef:
            DcmSMR smr
            CmResult ret = cm_Unknown
            CmEvent evt = cm_NotRaised

        assert(self.inited)

        smr = DcmSMR(t, o, l)
        (ret, evt) = self.cm_inst.do_track(smr)

        return (ret, evt)

However I got this error when compiling:

CmPy.cpp:1662:3: error: ‘__pyx_ctuple_enum__space_CmResult__and_enum__space_CmEvent’ was not declared in this scope
   __pyx_ctuple_enum__space_CmResult__and_enum__space_CmEvent __pyx_t_10;

I couldn't figure out what was the issue here.

You need to provide a Cython declaration of std::tuple .

Have a look at how std::pair is declared: https://github.com/cython/cython/blob/master/Cython/Includes/libcpp/utility.pxd

Also, syntax (ret, evt) = ... won't unpack a C++ std::tuple .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM