spacepaste

  1.  
  2. from cffi import FFI
  3. import numpy as np
  4. s = '''
  5. typedef struct
  6. {
  7. int a;
  8. int b;
  9. float c;
  10. double d;
  11. } mystruct;
  12. '''
  13. ffi = FFI()
  14. ffi.cdef(s)
  15. m_arr = ffi.new("mystruct[2]")
  16. #create array and fill with dummy data
  17. for k in range(2):
  18. m = m_arr[k]
  19. m.a = k
  20. m.b = k + 1
  21. m.c = k + 2.0
  22. m.d = k + 3.0
  23. print(m_arr)
  24. # dtype for structured array in Numpy
  25. dt = np.dtype({'names': ('a', 'b', 'c', 'd'),
  26. 'formats': ('i4', 'i4', 'f4', 'f8'),
  27. 'offset': (ffi.offsetof('mystruct', 'a'),
  28. ffi.offsetof('mystruct', 'b'),
  29. ffi.offsetof('mystruct', 'c'),
  30. ffi.offsetof('mystruct', 'd'),
  31. )
  32. })
  33. padding = ffi.sizeof('mystruct') - dt.itemsize
  34. if padding:
  35. # this padding takes into account aligning arrays of structs
  36. dt = np.dtype({'names': ('a', 'b', 'c', 'd','padding'),
  37. 'formats': ('i4', 'i4', 'f4', 'f8', 'S%d' % padding),
  38. 'offset': (ffi.offsetof('mystruct', 'a'),
  39. ffi.offsetof('mystruct', 'b'),
  40. ffi.offsetof('mystruct', 'c'),
  41. ffi.offsetof('mystruct', 'd'),
  42. )
  43. })
  44. # member size, 20 bytes
  45. print('size, manually', 4 + 4 + 4 + 8)
  46. # total size of struct, 24 bytes
  47. print('sizeof', ffi.sizeof(m_arr[0]))
  48. #reason is member padding in structs
  49. buf = ffi.buffer(m_arr)
  50. print(buf)
  51. x = np.frombuffer(buf, dtype=dt)
  52. print(x)
  53.