Search code examples
pythoncvariablesenumspython-cffi

Fetching a C variable value in an enum using its name (a Python string) in Python


Basically, I am wrapping a C API in Python (using CFFI (which is awesome)).

I have an enum in that C API:

typedef enum
{
    enum1 = value1;
    enum2 = value2;
    ...
} enumSomething;

In Python, I receive the name of a variable which is in that enumeration, as a string : "enum1". I would like to get value1.

Using CFFI, you can wrap an enum and access its members easily (here is an example). My problem here is that I have strings that represent the name of the variable, not the variable itself.

Thus, cwrapper.c."enum1" would not work (cwrapper being the name of the module that wraps and c the name returned by ffi.dlopen(libname) while wrapping the library).

I could make a dictionary that would map the variable name as a string to the real variable, such as:

enum = { "enum1" : cwrapper.c.enum1, "enum2" : cwrapper.c.enum2, ... } 

But at this point, I would better rewrite the enum as a Python dictionary.

I know I could also use a regex to read the C file, but I think there is still a better way for handling that, that I haven't thought of. Any idea?


Solution

  • cwrapper.c."enum1" is not valid syntax in Python in general. You need to use getattr:

    >>> getattr(cwrapper.c, "enum1")
    42
    

    However a cleaner approach is to get the actual type using typeof; then get its relements, which is a dictionary!

    >>> import cffi
    >>> ffi = cffi.FFI()
    >>> ffi.cdef('typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;')
    >>> typeof_strategy = ffi.typeof('strategy')
    >>> typeof_strategy.relements
    {'RANDOM': 0, 'SEARCH': 2, 'IMMEDIATE': 1}
    >>> typeof_strategy.relements['SEARCH']
    2