ctypes.struct(packed)中的sizeof与C中的压缩结构不匹配

jan*_*nco 7 c struct ctypes bit-fields python-3.x

我在C中有一个压缩结构,我想在Python中解析.我注意到sizeofC(使用GCC 4.9.2)和Python 3.4.2中的ctypes库之间的运算符返回的结构大小与位域的差异.

以下C代码按预期打印5:

#include <stdio.h>
#include <stdint.h>

typedef struct __attribute__((packed)) {
    uint32_t ch0 : 20;
    uint32_t ch1 : 20;
} pkt_t;

int main(){
    printf("sizeof(pkt_t): %d\n", sizeof(pkt_t));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

虽然Python中的(相同)代码打印8

import ctypes

class Packet(ctypes.LittleEndianStructure):
    _pack_ = 1
    _fields_ = [
        ('ch0', ctypes.c_uint32, 20),
        ('ch1', ctypes.c_uint32, 20),
    ]   

print(ctypes.sizeof(Packet()))
Run Code Online (Sandbox Code Playgroud)

看起来它_pack_ = 1等同__attribute__((aligned(1)))于C,而不是__attribute__((packed, aligned(1)))使结构尽可能紧密地打包.有没有办法packed为ctypes结构启用属性?

Gos*_*low 0

我不认为对齐是这里的问题,因此在 python 中将对齐设置为 1 没有达到预期的效果。

问题是 C 中的位域填充了给定的类型,但没有跨越边界。uint32_t 有 32 位,每个成员需要 20 位。所以每个成员都会被放入一个单独的uint32_t中,总共8个字节。

不知何故,packed 属性会导致 gcc 忽略该规则并总共使用 40 位。

另一方面,Python ctypes 遵循该规则并得到 8。