This is a cross-post of a question I asked in the cython-user group a day and a half ago, but have not yet gotten any replies, so I am trying my luck in a more general forum
I have been trying every which way to wrap this following code, with various degrees of errors. Plenty of searching had me stumbling upon similar questions and also an outstanding wishlist ticket, but honestly I am not sure if I am even on the right path.
plow_types.h:
namespace Plow {
    struct JobState {
      enum type {
        INITIALIZE = 0,
        RUNNING = 1,
        FINISHED = 2
      };
    };
    ...
    class JobFilterT {
     public:
      ...
      std::vector<JobState::type>  states;
      ...
So I am trying to wrap this Plow::JobState::type enum. The closest I got, after finding another similar post, was ending up with this attempt:
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 
And I get an error:
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’
I've tried to simply just define my own versions of the constants in my cython pyx and treat everything as int (vector[int] states) but the compiler complains about not knowing how to do conversions from int long to Plow::JobState::type.
I finally figured it out, after trying an unbelievable amount of combinations. It was not to far off from my last attempt before asking the question...
plow_types.pxd:
I needed to just forget about that JobState struct, and only wrap the enum. But I also needed to map them to new names in cython to avoid name collisions with other enums using that similar namespace technique.
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" 
Now I can refer to JobState_type in stuff like vector[JobState_type]. Then I used this approach to making my constants available in python, in a readonly way:
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()
This gives me a public instance of JobState, with readonly constant attributes. 
And when needing to convert back from a list of python values to a vector[JobState_type], I would do this:
someList = [JobState.RUNNING]
...
cdef:
    JobState_type i
    vector[JobState_type] vec_states
for i in someList:
    vec_states.push_back(i)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With