Can I expose a C++ enum
to SWIG as a real entity rather than a set of constants so I can enumerate over them in python code?
相关问题
- how to define constructor for Python's new Nam
- Sorting 3 numbers without branching [closed]
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- How to compile C++ code in GDB?
I faced the same issue. I hope that SWIG soon supports C++11's
enum class
.Here's a hack that convinces SWIG to put enums in a structure:
In
.cpp
code you now must useMyEnum::Value1
and in Python code it isMyEnum.Value1
. Although convoluted, thetypedef
prevents having to change existing code that uses the enum everywhere and the SWIG %rename makes the enum have the same name in the SWIG wrapper.In Python you can enumerate the values with a little code:
It's not pretty, and I'd love to see a better solution.
I'm pretty sure you're looking for are...
typemaps: Since type handling is so central to wrapper code generation, SWIG allows it to be completely defined (or redefined) by the user. To do this, a special %typemap directive is used. (SWIG Doc2.0)
For all the info you could ever need about typemaps here is the link to the SWIG documentation about it. http://www.swig.org/Doc2.0/Typemaps.html#Typemaps_nn2
Typemaps should allow you to tell SWIG to convert c++ enums to python objects that you want.
We can make something that lets you enumerate over it in Python, with relatively little intrusion into the C++ headers it wraps. For example if we have a header file:
It expands to be just a regular enum in C++, but is sufficient as a header file to expose the enum members in Python.
Using
%typemap(constcode)
we can inject some extra things into our Python module for the enum, but we need to know the name of the enum to do this; The SWIG typeinfo object for it is just as if it were anint
. Therefore we use a bit of a hack in ourPYTHON_ENUM
macro to store the name of the enum in a custom typemap.This creates a PyDict in the intermediate module for every enum that has key/value pairs. There's also some
%pythoncode
glue there to tie the PyDict in the intermediate module into the exposed module. (I'm not sure how to refer to the intermediate module by name in it, other than hardcoded as _test - change as needed).This is sufficient that I can then use it as: