Предоставляет ли ctypes перечисления и флаги? - PullRequest
5 голосов
/ 23 июня 2010

У меня есть API, который я хотел бы использовать из python. Этот API содержит флаги и перечисления, реализованные с помощью # 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

Если игнорировать все остальное, кроме перечислений и флагов, мои привязки должны перевести это на:

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

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

Предоставляет ли ctypes механизмы для этого? Если нет, то просто расскажите о своем «обычном» инструменте для обработки флагов и перечислений в привязках python.

Ответы [ 2 ]

4 голосов
/ 23 июня 2010

Я немного разочарован, чтобы ответить на этот вопрос сам. Тем более, что я все это нашел в руководстве f *.

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

Чтобы завершить свой ответ, я напишу код, который оборачивает элемент.

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 преобразует этот изящный список в целое число.

3 голосов
/ 23 июня 2010

Почему бы вам не использовать c_uint для параметра enum, а затем использовать подобное отображение (перечисления обычно представляют собой целые значения без знака):

в С:

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

и в Python:

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

    MY_VAR = 1
    MY_OTHERVAR = 2


myfunc.argtypes = [c_uint, ...]

Затем вы можете передать MyEnum поля в функцию.

Если вы хотите получить строковое представление для перечисляемых значений, вы можете использовать dictionary в классе MyEnum.

...