Python ctypes对齐数据结构

火狐

我有一个编译为共享库的C库,并且想围绕它建立一个ctypes接口,以从Python调用C函数。

通常它可以正常工作,但是C库中有一个double数组的定义:

typedef double __attribute__ ((aligned (32))) double_array[512];

我找不到直接访问此类型的方法,因此我在Python中定义:

DoubleArray = ctypes.c_double * 512

尽管这在大多数情况下都可以解决,但有时C库会出现段错误,我想这DoubleArray因为未对齐到32个字节而引起的(也许库期望这样做是因为数据已传递给AVX)。

我怎么解决这个问题?

孙ry

数组最多比对齐少31个字节。要获得对齐的数组,请过度分配31个字节,然后,如果基址未对齐,请添加一个偏移量以使其对齐。这是一个通用函数:

def aligned_array(alignment, dtype, n):
    mask = alignment - 1
    if alignment == 0 or alignment & mask != 0:
        raise ValueError('alignment is not a power of 2')
    size = n * ctypes.sizeof(dtype) + mask
    buf = (ctypes.c_char * size)()
    misalignment = ctypes.addressof(buf) & mask
    if misalignment:
        offset = alignment - misalignment        
    else:
        offset = 0
    return (dtype * n).from_buffer(buf, offset)

例如:

>>> arr = aligned_array(2**4, ctypes.c_double, 512)
>>> hex(ctypes.addressof(arr))
'0x1754410'
>>> arr = aligned_array(2**8, ctypes.c_double, 512)
>>> hex(ctypes.addressof(arr))
'0x1755500'
>>> arr = aligned_array(2**12, ctypes.c_double, 512)
>>> hex(ctypes.addressof(arr))
'0x1757000'
>>> arr = aligned_array(2**16, ctypes.c_double, 512)
>>> hex(ctypes.addressof(arr))
'0x1760000'

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章