2015-06-23 14 views
5

Sto provando a racchiudere una classe enum in un file di intestazione C++ da utilizzare in un progetto cython. Ho cercato su google e non riesco a scoprire come ottenerlo - è supportato?Wrap enum class per cython

+1

Puoi elaborare un esempio con 'cdef enum Foo: [...]' non risponde alle tue esigenze? – coincoin

+1

Non sto eseguendo il wrapping di un c enum, ma di una classe en ++ C++ quindi non funziona – user3684792

+0

Esegui l'enum come un 'ctypedef' e il contenuto dell'enumerazione in un namespace? (Non ho provato questo, ma sembra che potrebbe funzionare) – DavidW

risposta

6

classe CPP

enum class Color {red, green = 20, blue}; 

Definizione di tipo

cdef extern from "colors.h": 
    cdef cppclass Color: 
    pass 

Definizione di tipi di colore implementazione

cdef extern from "colors.h" namespace "Color": 
    cdef Color red 
    cdef Color green 
    cdef Color blue 

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] 
0

Ecco una soluzione alternativa che utilizza la possibilità di modificare il nome degli identificatori di cython e C++.

header.hpp

namespace foo { 
enum class Bar : uint32_t { 
    BAZ, 
    QUUX 
}; 
} 

header.pxd

cdef extern from "header.hpp" namespace "foo::Bar": 
    cdef enum Bar "foo::Bar": 
     BAZ, 
     QUUX 

main.pyx

from header cimport * 
cdef void doit(Bar b): 
    pass 

doit(BAZ) # Not Bar.BAZ, which would have been nicer. 

E 'efficace tellin g cython che esiste uno spazio dei nomi chiamato "foo :: Bar" e inserisce un enum di tipo C in esso. Per contrastare il fatto che Bar diventerebbe altrimenti "foo :: Bar :: Bar" a cui viene dato anche un nome sovrascritto. Significa che Bar :: BAZ viene chiamato BAZ in cython, piuttosto che Bar.BAZ che sarebbe una rappresentazione più idiomatica delle classi enum, ma sembra abbastanza vicino.