11

这是我在一天半前在 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’

两者任一:

  1. 如何正确包装这个嵌套枚举?
  2. 这甚至有必要尝试完全包装它,还是我可以通过其他方式实现访问这些“命名空间”常量的目标?我是否应该完全忽略这些结构,并在我的 pyx 中定义我自己的常量版本,并使用匹配的 int 值?

我试图在我的 cython pyx 中简单地定义我自己的常量版本并将所有内容都视为 int( vector[int] states) 但编译器抱怨不知道如何进行从int longto的转换Plow::JobState::type

4

1 回答 1

8

在尝试了令人难以置信的组合之后,我终于想通了。在问这个问题之前,离我最后一次尝试不远了……

plow_types.pxd:

我需要忘记那个JobState结构,只包装枚举。但我还需要将它们映射到 cython 中的新名称,以避免使用类似的命名空间技术与其他枚举发生名称冲突。

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 中可用:

工作.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这给了我一个具有只读常量属性的公共实例。

当需要从 python 值列表转换回 a 时vector[JobState_type],我会这样做:

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

for i in someList:
    vec_states.push_back(i)
于 2013-03-22T09:12:48.393 回答