在ctypes.Structure中使用枚举

13 投票
2 回答
26655 浏览
提问于 2025-04-15 14:58

我有一个结构体,是通过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_intc_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

撰写回答