代码之家  ›  专栏  ›  技术社区  ›  Kamil Kisiel

在ctypes.structure中使用枚举

  •  10
  • Kamil Kisiel  · 技术社区  · 15 年前

    我有一个通过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 回复  |  直到 15 年前
        1
  •  9
  •   Andrey Vlasovskikh    15 年前

    至少对于GCC enum 只是一个简单的数字类型。它可以是8位、16位、32位、64位或其他(我用64位值测试过它)以及 signed unsigned . 我想不能超过 long long int 但实际上你应该检查一下 枚举 选择一些像 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;
    }
    

    还有巨蟒一号:

    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
    
        2
  •  5
  •   Martin v. Löwis    15 年前

    使用 c_int c_uint 会很好的。或者,有一个 recipe in the cookbook 对于枚举类。