在 ctypes.Structure 中使用枚举

发布于 2024-08-07 19:07:00 字数 498 浏览 5 评论 0原文

我有一个通过 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 还是?

I have a struct I'm accessing via ctypes:

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

So far I have Python code like:

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

But I'm not sure what to use for the batch_op enum. Should I just map it to a c_int or ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可是我不能没有你 2024-08-14 19:07:00

至少对于 GCC 来说 enum 只是一个简单的数字类型。它可以是 8 位、16 位、32 位、64 位或任何位(我已经使用 64 位值对其进行了测试)以及有符号或无符号。我猜它不能超过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

At least for GCC enum is just a simple numeric type. It can be 8-, 16-, 32-, 64-bit or whatever (I have tested it with 64-bit values) as well as signed or unsigned. I guess it cannot exceed long long int, but practically you should check the range of your enums and choose something like c_uint.

Here is an example. The C program:

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;
}

and the Python one:

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
叹沉浮 2024-08-14 19:07:00

使用 c_intc_uint 就可以了。或者,食谱中有一个枚举类的食谱

Using c_int or c_uint would be fine. Alternatively, there is a recipe in the cookbook for an Enumeration class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文