2010-06-23 3 views
4

J'ai une API que j'aimerais utiliser de Python. Cette API contient des indicateurs et des énumérations implémentés aveC#define.Est-ce que ctypes fournit quelque chose pour enums et drapeaux?

// 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 

Si ignorant tout le reste, sauf les énumérations et les drapeaux, mes liaisons devraient traduire cela:

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

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

-t-ctypes fournir des mécanismes pour le faire en ligne droite? Si ce n'est pas le cas, parlez de votre outil "habituel" pour gérer les drapeaux et les enums dans les bindings python.

Répondre

4

Je suis un peu déçu de répondre moi-même à cette question. Surtout depuis que j'ai tout trouvé dans le manuel f *.

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

Pour terminer ma réponse, je vais écrire un code qui fait envelopper un élément. Encode_flags transforme cette liste astucieuse en un nombre entier

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"]) 

+0

Je suis sûr que maintenant, puisque vous avez lu la documentation, vous savez qu'en plus de toutes les autres solutions, vous auriez pu utiliser une propriété: http://docs.python.org/library/ functions.html # propriété –

3

Pourquoi utilisez-vous pas c_uint pour le paramètre enum puis utilisez une application comme celui-ci (énumérations sont généralement des valeurs entières non signées):

dans C:

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

et en Python:

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

    MY_VAR = 1 
    MY_OTHERVAR = 2 


myfunc.argtypes = [c_uint, ...] 

Vous pouvez ensuite transmettre les champs MyEnum à la fonction.

Si vous voulez une représentation sous forme de chaîne pour les valeurs énumérées, vous pouvez utiliser un dictionary dans la classe MyEnum.

+0

Oui. peut être fait de cette façon. Bien que je cherche un drapeau -> traduction de forme textuelle, sous forme automatisée. – Cheery

+0

Vous pouvez substituer la méthode '__getattr__' pour renvoyer la représentation textuelle des indicateurs ou définir des variables de chaînes statiques supplémentaires dans la classe. –

Questions connexes