2009-10-09 32 views
8

Tôi có một struct Tôi đang truy cập qua ctypes:Sử dụng enums trong ctypes.Structure

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

Cho đến nay tôi có mã Python như:

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

Nhưng tôi không chắc chắn những gì để sử dụng cho batch_op enum. Tôi có nên chỉ lập bản đồ cho một số c_int hay không?

Trả lời

9

Ít nhất đối với GCC enum chỉ là một loại số đơn giản. Nó có thể là 8-, 16-, 32-, 64-bit hoặc bất kỳ thứ gì (tôi đã thử nghiệm nó với các giá trị 64 bit) cũng như signed hoặc unsigned. Tôi đoán nó không thể vượt quá long long int, nhưng thực tế bạn nên kiểm tra phạm vi enum của bạn và chọn một cái gì đó như c_uint.

Đây là một ví dụ. Chương trình 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; 
} 

và Python một:

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

Sử dụng c_int hoặc c_uint sẽ ổn. Ngoài ra, có một recipe in the cookbook cho một lớp liệt kê.

Các vấn đề liên quan