在ctypes.Structure中使用枚举
我有一个结构体,是通过ctypes来访问的:
struct attrl {
char *name;
char *resource;
char *value;
struct attrl *next;
enum batch_op op;
};
到目前为止,我的Python代码是这样的:
# struct attropl
class attropl(Structure):
pass
attrl._fields_ = [
("next", POINTER(attropl)),
("name", c_char_p),
("resource", c_char_p),
("value", c_char_p),
但是我不太确定该用什么来表示batch_op
这个枚举。难道我应该把它映射成c_int
吗,还是有其他的选择?
2 个回答
5
使用 c_int
或 c_uint
是可以的。另外,还有一个关于枚举类的教程可以参考。
13
对于GCC来说,enum
其实就是一种简单的数字类型。它可以是8位、16位、32位、64位,或者其他位数(我测试过64位的值),还可以是signed
(有符号)或unsigned
(无符号)。我猜它的范围不会超过long long int
,但实际上你应该检查一下你的enum
的范围,然后选择像c_uint
这样的类型。
这里有一个例子。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;
}
还有Python的程序:
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