为cython包装枚举类

use*_*792 10 c++ cython c++11 enum-class

我试图将一个枚举类包装在c ++头文件中,以便在cython项目中使用.我已经google了一下,无法找到如何实现这一点 - 是否支持?

oz1*_*oz1 10

最新的 cython (3.x) 直接支持 c++ enum class,记录如下:https: //cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html#scoped-enumerations

这是一个例子:

// cpp header
enum class State: int
{
    Good,
    Bad,
    Unknown,
};


const char* foo(State s){
    switch (s){
        case State::Good:
            return "Good";
        case State::Bad:
            return "Bad";
        case State::Unknown:
            return "Unknown";
    }
}
Run Code Online (Sandbox Code Playgroud)

赛通这边

cdef extern from "test.h":
    cpdef enum class State(int):
        Good,
        Bad,
        Unknown,

    const char* foo(State s)
    
def py_foo(State s):
    return foo(s)
Run Code Online (Sandbox Code Playgroud)

来电py_foo(State.Good)返回b'Good'


use*_*030 6

CPP课程

enum class Color {red, green = 20, blue}; 
Run Code Online (Sandbox Code Playgroud)

类型的定义

cdef extern from "colors.h":
  cdef cppclass Color:
    pass
Run Code Online (Sandbox Code Playgroud)

颜色类型的定义

cdef extern from "colors.h" namespace "Color":
  cdef Color red
  cdef Color green
  cdef Color blue
Run Code Online (Sandbox Code Playgroud)

Python实现

cdef class PyColor:
  cdef Color thisobj
  def __cinit__(self, int val):
    self.thisobj = <Color> val

  def get_color_type(self):
    cdef c = {<int>red : "red", <int> green : "green", <int> blue : "blue"}
    return c[<int>self.thisobj]
Run Code Online (Sandbox Code Playgroud)

  • 对于 Cython 版本 &gt;= 3.0 考虑这个答案:/sf/answers/4699726181/ (2认同)

小智 5

另一种允许使用Cython 文档中提到的PEP-435 枚举的替代方法如下:

foo.h

namespace foo {
enum class Bar : uint32_t {
    Zero = 0,
    One = 1
};
}
Run Code Online (Sandbox Code Playgroud)

foo.pxd

from libc.stdint cimport uint32_t

cdef extern from "foo.h" namespace 'foo':

    cdef enum _Bar 'foo::Bar':
        _Zero 'foo::Bar::Zero'
        _One  'foo::Bar::One'


cpdef enum Bar:
    Zero = <uint32_t> _Zero
    One  = <uint32_t> _One
Run Code Online (Sandbox Code Playgroud)

主文件

from foo cimport Bar

print(Bar.Zero)
print(Bar.One)

# or iterate over elements
for value in Bar:
    print(value)
Run Code Online (Sandbox Code Playgroud)