Cheery
Cheery

Reputation: 25443

Does ctypes provide anything for enums and flags?

I have an API I'd like to use from python. That API contains flags and enums implemented with #define.

// it's just almost C so don't bother adding the typedef and parenthesis diarrhea here.
routine(API_SOMETHING | API_OTHERTHING)
stuff = getflags()
? stuff & API_SOMETHING

action(API_INTERESTING)
mode = getaction()
? mode == INTERESTING

If ignoring everything else except enums and flags now, my bindings should translate this to:

routine(["something", "otherthing"])
stuff = getflags()
if 'something' in stuff

action('interesting')
mode = getaction()
if mode == 'interesting'

Does ctypes provide mechanisms to do this straight out? If not then just tell about your 'usual' tool for handling flags and enums in python bindings.

Upvotes: 5

Views: 5373

Answers (2)

Cheery
Cheery

Reputation: 25443

I'm a bit disappointed to answer to this question myself. Especially since I found it all from the f* manual.

http://docs.python.org/library/ctypes.html#calling-functions-with-your-own-custom-data-types

To complete my answer, I'll write some code that does wrap an item.

from ctypes import CDLL, c_uint, c_char_p

class Flag(object):
    flags = [(0x1, 'fun'), (0x2, 'toy')]
    @classmethod
    def from_param(cls, data):
        return c_uint(encode_flags(self.flags, data))

libc = CDLL('libc.so.6')
printf = libc.printf
printf.argtypes = [c_char_p, Flag]

printf("hello %d\n", ["fun", "toy"])

encode_flags transforms that nifty list into an integer.

Upvotes: 3

the_void
the_void

Reputation: 5538

Why don't you use c_uint for the enum parameter and then use a mapping like this (enums are usually unsigned integer values):

in C:

typedef enum {
  MY_VAR      = 1,
  MY_OTHERVAR = 2
} my_enum_t;

and in Python:

class MyEnum():
    __slots__ = ('MY_VAR', 'MY_OTHERVAR')

    MY_VAR = 1
    MY_OTHERVAR = 2


myfunc.argtypes = [c_uint, ...]

You can then pass MyEnum fields to the function.

If you want a string representation for the enumerated values, you can use a dictionary in the MyEnum class.

Upvotes: 3

Related Questions