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