python 在 ctypes.Structure 中使用枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1546355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:33:00  来源:igfitidea点击:

Using enums in ctypes.Structure

pythonenumsctypes

提问by Kamil Kisiel

I have a struct I'm accessing via ctypes:

我有一个通过 ctypes 访问的结构:

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

So far I have Python code like:

到目前为止,我的 Python 代码如下:

# 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_openum. Should I just map it to a c_intor ?

但我不确定该batch_op枚举使用什么。我应该将它映射到 ac_int还是 ?

采纳答案by Andrey Vlasovskikh

At least for GCC enumis 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 signedor 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.

至少对于 GCCenum来说只是一个简单的数字类型。它可以是 8 位、16 位、32 位、64 位或其他(我已经用 64 位值对其进行了测试)以及signedunsigned. 我想它不能超过long long int,但实际上您应该检查enums的范围并选择类似c_uint.

Here is an example. The C 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;
}

and the Python one:

和 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

回答by Martin v. L?wis

Using c_intor c_uintwould be fine. Alternatively, there is a recipe in the cookbookfor an Enumeration class.

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