Wrapping struct с вложенным перечислением - ссылка в векторном шаблоне

Это кросс-пост вопроса, который я задал в группе cython-user, полтора дня назад, но еще не получил никаких ответов, поэтому Я пробовал свою удачу на более общем форуме

Я пробовал каждый способ обернуть этот следующий код с различными степенями ошибок. Множество поисков заставили меня споткнуться на подобные вопросы, а также выдающийся билет в список желаний, но, честно говоря, я не уверен, что я даже на правильном пути.

plow_types.h:

namespace Plow {

    struct JobState {
      enum type {
        INITIALIZE = 0,
        RUNNING = 1,
        FINISHED = 2
      };
    };
    ...
    class JobFilterT {
     public:
      ...
      std::vector<JobState::type>  states;
      ...

Итак, я пытаюсь обернуть это перечисление Plow::JobState::type. Ближайший я получил после того, как нашел еще одну подобную запись, оказался в конце этой попытки:

plow_types.pxd:

cdef extern from "rpc/plow_types.h" namespace "Plow":

    enum JobState_type "Plow::JobState::type":
        INITIALIZE "Plow::JobState::INITIALIZE"
        RUNNING "Plow::JobState::RUNNING"
        FINISHED "Plow::JobState::FINISHED"

    struct JobState:
        JobState_type type
    ...
    cdef cppclass JobFilterT:
        vector[JobState_type] states 

И я получаю сообщение об ошибке:

src/plow.cpp: In function ‘std::vector<Plow::JobState::type, std::allocator<Plow::JobState::type> > __pyx_convert_vector_from_py_enum__Plow_3a__3a_JobState_3a__3a_type(PyObject*)’:
src/plow.cpp:6688: error: invalid conversion from ‘long int’ to ‘Plow::JobState::type’

Либо/или:

  • Как я могу правильно обернуть это вложенное перечисление?
  • Нужно ли даже пытаться обернуть это точно или я могу выполнить свою задачу доступа к этим константам с именами другими способами? Должен ли я полностью игнорировать эти структуры и определять мои собственные версии констант в моем pyx с соответствующими значениями int?

Я попытался просто просто определить свои собственные версии констант в моем pyx pyython и рассматривать все как int (vector[int] states), но компилятор жалуется, что не знает, как делать преобразования с int long до Plow::JobState::type.

Ответ 1

Я, наконец, понял это, попробовав невероятное количество комбинаций. Это не было далеко от моей последней попытки, прежде чем задавать вопрос...

plow_types.pxd:

Мне нужно было просто забыть об этой структуре JobState и только обернуть перечисление. Но мне также нужно было сопоставить их с новыми именами в цитоне, чтобы избежать столкновений имен с другими перечислениями, используя эту аналогичную технику пространства имен.

cdef extern from "rpc/plow_types.h" namespace "Plow":

    ctypedef enum JobState_type "Plow::JobState::type":
        JOBSTATE_INITIALIZE "Plow::JobState::INITIALIZE"
        JOBSTATE_RUNNING "Plow::JobState::RUNNING"
        JOBSTATE_FINISHED "Plow::JobState::FINISHED" 

Теперь я могу ссылаться на JobState_type на вещи типа vector[JobState_type]. Затем я использовал этот подход для того, чтобы сделать мои константы доступными на python в режиме чтения:

job.pyx:

cimport cython

@cython.internal
cdef class _JobState:
    cdef:
        readonly int INITIALIZE 
        readonly int RUNNING 
        readonly int FINISHED 

    def __cinit__(self):
        self.INITIALIZE = JOBSTATE_INITIALIZE
        self.RUNNING = JOBSTATE_RUNNING
        self.FINISHED = JOBSTATE_FINISHED

JobState = _JobState()

Это дает мне публичный экземпляр JobState с постоянными атрибутами readonly.

И когда вам нужно преобразовать обратно из списка значений python в vector[JobState_type], я бы сделал следующее:

someList = [JobState.RUNNING]
...
cdef:
    JobState_type i
    vector[JobState_type] vec_states

for i in someList:
    vec_states.push_back(i)