tags:

views:

63

answers:

2

Hi all

I have a ctypes structure.

class S1 (ctypes.Structure):
    _fields_ = [
    ('A',     ctypes.c_uint16 * 10),
    ('B',     ctypes.c_uint32),
    ('C',     ctypes.c_uint32) ]

if I have X=S1(), I would like to return a dictionary out of this object: Example, if I do something like: Y = X.getdict() or Y = getdict(X), then Y might look like:

{ 'A': [1,2,3,4,5,6,7,8,9,0], 
  'B': 56,
  'C': 8986 }

Any help ?

A: 

Probably something like this:

def getdict(struct):
    return dict((field, getattr(struct, field)) for field, _ in struct._fields_)

>>> x = S1()
>>> getdict(x)
{'A': <__main__.c_ushort_Array_10 object at 0x100490680>, 'C': 0L, 'B': 0L}

As you can see, it works with numbers but it doesn't work as nicely with arrays -- you will have to take care of converting arrays to lists yourself. A more sophisticated version that tries to convert arrays is as follows:

def getdict(struct):
    result = {}
    for field, _ in struct._fields_:
         value = getattr(struct, field)
         if hasattr(value, "_length_") and hasattr(value, "_type_"):
             # Probably an array
             value = list(value)
         elif hasattr(value, "_fields_"):
             # Probably another struct
             value = getdict(value)
         result[field] = value
    return result
Tamás
Nice ! Nearly there. I am still facing a new situation in which one ctype structure S1 has a field that is of another type S2. Wonder if that can be converted too.
G.A.
I've added another branch that tries to handle nested structs (assuming that structs can be recognised by their `_fields_` attribute). Not sure if this works, though, I haven't tested it.
Tamás
Will test and let you know. Thanks.
G.A.
It works !! Thanks. I'm trying to see if I can do the reverse. That is, given a dictionary of values, set the values in a ctype (which may again have embedded subtypes). I stuck at the trying to find out which type is the embedded type.
G.A.
+1  A: 

How about something like:

class S1(ctypes.Structure):
    _fields_ = [ ... ]

    def getdict(self):
        dict((f, getattr(self, f)) for f, _ in self._fields_)
llasram