Python: Can we convert a ctypes structure to a dictionary?

后端 未结 3 1299
没有蜡笔的小新
没有蜡笔的小新 2021-02-20 08:02

I have a ctypes structure.

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


        
相关标签:
3条回答
  • 2021-02-20 08:31

    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 the type is not a primitive and it evaluates to False ...
             if (type(value) not in [int, long, float, bool]) and not bool(value):
                 # it's a null pointer
                 value = None
             elif 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
    

    If you have numpy and want to be able to handle multidimensional C arrays, you should add import numpy as np and change:

     value = list(value)
    

    to:

     value = np.ctypeslib.as_array(value).tolist()
    

    This will give you a nested list.

    0 讨论(0)
  • How about something like:

    class S1(ctypes.Structure):
        _fields_ = [ ... ]
    
        def getdict(self):
            dict((f, getattr(self, f)) for f, _ in self._fields_)
    
    0 讨论(0)
  • 2021-02-20 08:44

    A little bit more general purpose to handle double arrays, and arrays of structures, and bitfields.

    def getdict(struct):
        result = {}
        #print struct
        def get_value(value):
             if (type(value) not in [int, long, float, bool]) and not bool(value):
                 # it's a null pointer
                 value = None
             elif hasattr(value, "_length_") and hasattr(value, "_type_"):
                 # Probably an array
                 #print value
                 value = get_array(value)
             elif hasattr(value, "_fields_"):
                 # Probably another struct
                 value = getdict(value)
             return value
        def get_array(array):
            ar = []
            for value in array:
                value = get_value(value)
                ar.append(value)
            return ar
        for f  in struct._fields_:
             field = f[0]
             value = getattr(struct, field)
             # if the type is not a primitive and it evaluates to False ...
             value = get_value(value)
             result[field] = value
        return result
    
    0 讨论(0)
提交回复
热议问题