在python ctypes中控制内存对齐



我正在研究使用ctypes来使用C函数操作必须在16字节边界上对齐的SSE (__m128)数据。

我找不到一种简单的方法来控制ctypes分配的内存对齐,所以,现在,我让ctypes调用一个提供正确对齐的内存缓冲区的C函数。

我使用这种方法的问题是,我必须手动显式释放该内存,以防止它被泄露。

是否有一种方法来控制ctypes分配的内存对齐?或者是否有一种方法来注册一个清理函数来释放由ctypes调用的C函数分配的内存(除了标准的python操作符__del__) ?

最佳路径是什么

我已经花了一些时间来调查,我想出了一个函数,应该允许我分配任意对齐的内存与ctypes,基本上依赖于ctypes应该保持一个引用在未对齐的内存缓冲区,而有一个实例开始在一个对齐的位置在缓冲区。

还需要在生产中测试。

import ctypes
def ctypes_alloc_aligned(size, alignment):
  bufSize = size+(alignment-1)
  raw_memory = bytearray(bufSize)
  ctypes_raw_type = (ctypes.c_char * bufSize)
  ctypes_raw_memory = ctypes_raw_type.from_buffer(raw_memory)
  raw_address = ctypes.addressof(ctypes_raw_memory)
  offset = raw_address % alignment
  offset_to_aligned = (alignment - offset) % alignment
  ctypes_aligned_type = (ctypes.c_char * (bufSize-offset_to_aligned))
  ctypes_aligned_memory = ctypes_aligned_type.from_buffer(raw_memory, offset_to_aligned)
  return ctypes_aligned_memory

我认为c_ulonglong(64位)必须是64位对齐的;这是一个开始。然后,文档建议您可以使用_pack_来控制结构的对齐。这两个并不完全是您想要的,但是通过组合它们,您可以分配8字节对齐的无孔结构。

让我们假设一个结构体有3个8字节对齐的元素.v0, .v1, .v2。使用addressof()查看结构体是否为16字节对齐。如果是,使用.v0.v1作为128位值;如果不是,使用.v1.v2

最新更新