首页 > 解决方案 > 如何为返回枚举元组的 C++ 函数编写 cython 包装器?

问题描述

我有一个C++类如下所示:

// 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};
  }
};

还有一些cython包装:

// 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)

但是我在编译时遇到了这个错误:

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;

我无法弄清楚这里有什么问题。

标签: pythonc++cythoncpython

解决方案


您需要提供一个 Cython 声明std::tuple

看看如何std::pair声明:https ://github.com/cython/cython/blob/master/Cython/Includes/libcpp/utility.pxd

此外,语法(ret, evt) = ...不会解压缩 C++ std::tuple


推荐阅读