Skip to content

Instantly share code, notes, and snippets.

@inactivist
Last active March 15, 2023 15:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save inactivist/4ef7058c2132fa16759d to your computer and use it in GitHub Desktop.
Save inactivist/4ef7058c2132fa16759d to your computer and use it in GitHub Desktop.
Convert CFFI cdata structure to Python dict.
"""
Convert a CFFI cdata structure to Python dict.
Based on http://stackoverflow.com/q/20444546/1309774 with conversion of
char[] to Python str.
Usage example:
>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.cdef('''
... struct foo {
... int a;
... char b[10];
... };
... ''')
>>> foo = ffi.new("struct foo*")
>>> foo.a = 10
>>> foo.b = "Hey"
>>> foo_elem = foo[0]
>>> foo_dict = convert_to_python(foo_elem)
>>> print foo_dict
{'a': 10, 'b': 'Hey'}
"""
def __convert_struct_field( s, fields ):
for field,fieldtype in fields:
if fieldtype.type.kind == 'primitive':
yield (field,getattr( s, field ))
else:
yield (field, convert_to_python( getattr( s, field ) ))
def convert_to_python(s):
type=ffi.typeof(s)
if type.kind == 'struct':
return dict(__convert_struct_field( s, type.fields ) )
elif type.kind == 'array':
if type.item.kind == 'primitive':
if type.item.cname == 'char':
return ffi.string(s)
else:
return [ s[i] for i in range(type.length) ]
else:
return [ convert_to_python(s[i]) for i in range(type.length) ]
elif type.kind == 'primitive':
return int(s)
@bizulk
Copy link

bizulk commented Apr 25, 2018

Does not work with me as I have fields of "pointer" type.
May the module inspect shoul be another way to do it ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment