Python ctypes对齐数据结构 [英] Python ctypes align data structure

查看:181
本文介绍了Python ctypes对齐数据结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C库,该库已编译为共享库,并希望围绕它建立一个ctypes接口以从Python调用C函数.

I have a C library that is compiled to a shared object and want to build a ctypes interface around it to call the C functions from Python.

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

In general it works fine but there is this definition of a double array in the C library:

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

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

I found no way to access this type directly, so I defined in Python:

DoubleArray = ctypes.c_double * 512

尽管这种情况在大多数情况下都可以解决,但有时C库会出现段错误,我想是因为DoubleArray未与32个字节对​​齐(可能是库期望如此,因为数据已传递到AVX)而发生.

While this works out in most cases, sometimes the C library segfaults and I guess this happens because DoubleArray is not aligned to 32 bytes (maybe the library expects this because the data is passed to AVX).

我该如何解决这个问题?

How can I solve this problem?

推荐答案

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

The array is at most 31 bytes shy of alignment. To get an aligned array, over-allocate by 31 bytes and then, if the base address is misaligned, add an offset to make it aligned. Here's a generic function for this:

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'

这篇关于Python ctypes对齐数据结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆