2009-10-09 16 views
8

Mam struct mam dostępem poprzez ctypes:Korzystanie teksty stałe w ctypes.Structure

struct attrl { 
    char *name; 
    char *resource; 
    char *value; 
    struct attrl *next; 
    enum batch_op op; 
}; 

tej pory mam kod Python jak:

# struct attropl 
class attropl(Structure): 
    pass 
attrl._fields_ = [ 
     ("next", POINTER(attropl)), 
     ("name", c_char_p), 
     ("resource", c_char_p), 
     ("value", c_char_p), 

Ale nie jestem pewien, co do użyj do wyliczenia batch_op. Czy powinienem go po prostu odwzorować na c_int lub?

Odpowiedz

9

Przynajmniej dla GCC enum to tylko prosty typ numeryczny. Może mieć wartość 8, 16, 32, 64-bitową lub inną (testowałem ją z wartościami 64-bitowymi), a także signed lub unsigned. Chyba nie może przekroczyć wartości long long int, ale praktycznie powinieneś sprawdzić zakres swoich enum s i wybrać coś w rodzaju c_uint.

Oto przykład. Program C:

enum batch_op { 
    OP1 = 2, 
    OP2 = 3, 
    OP3 = -1, 
}; 

struct attrl { 
    char *name; 
    struct attrl *next; 
    enum batch_op op; 
}; 

void f(struct attrl *x) { 
    x->op = OP3; 
} 

i Python jeden:

from ctypes import (Structure, c_char_p, c_uint, c_int, 
    POINTER, CDLL) 

class AttrList(Structure): pass 
AttrList._fields_ = [ 
    ('name', c_char_p), 
    ('next', POINTER(AttrList)), 
    ('op', c_int), 
] 

(OP1, OP2, OP3) = (2, 3, -1) 

enum = CDLL('./libenum.so') 
enum.f.argtypes = [POINTER(AttrList)] 
enum.f.restype = None 

a = AttrList(name=None, next=None, op=OP2) 
assert a.op == OP2 
enum.f(a) 
assert a.op == OP3 
4

Używanie c_int lub c_uint byłoby w porządku. Alternatywnie istnieje klasa recipe in the cookbook dla klasy wyliczeniowej.

Powiązane problemy