Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在给定的ctypes结构打包示例中sizeof会发生变化?_Python_C_Struct_Padding_Ctypes - Fatal编程技术网

Python 为什么在给定的ctypes结构打包示例中sizeof会发生变化?

Python 为什么在给定的ctypes结构打包示例中sizeof会发生变化?,python,c,struct,padding,ctypes,Python,C,Struct,Padding,Ctypes,若能对以下代码的输出给出任何解释,我将不胜感激。我不明白为什么sizeof(struct_2)和sizeof(my_struct_2)是不同的,只要sizeof(struct_1)和sizeof(c_int)是相同的 似乎ctypes以某种不同的方式在struct中打包struct from ctypes import * class struct_1(Structure): pass int8_t = c_int8 int16_t = c_int16 uint8_t = c_uint

若能对以下代码的输出给出任何解释,我将不胜感激。我不明白为什么
sizeof(struct_2)
sizeof(my_struct_2)
是不同的,只要
sizeof(struct_1)
sizeof(c_int)
是相同的

似乎
ctypes
以某种不同的方式在
struct
中打包
struct

from ctypes import *

class struct_1(Structure):
    pass
int8_t = c_int8
int16_t = c_int16
uint8_t = c_uint8
struct_1._fields_ = [
    ('tt1', int16_t),
    ('tt2', uint8_t),
    ('tt3', uint8_t),
]

class struct_2(Structure):
    pass
int8_t = c_int8
int16_t = c_int16
uint8_t = c_uint8
struct_2._fields_ = [
    ('t1', int8_t),
    ('t2', uint8_t),
    ('t3', uint8_t),
    ('t4', uint8_t),
    ('t5', int16_t),
    ('t6', struct_1),
    ('t7', struct_1 * 6),
]

class my_struct_2(Structure):
    #_pack_ = 1  # This will give answer as 34
    #_pack_ = 4  #36
    _fields_ = [
    ('t1', c_int8),
    ('t2', c_uint8),
    ('t3', c_uint8),
    ('t4', c_uint8),
    ('t5', c_int16),
    ('t6', c_int),
    ('t7', c_int * 6),
]

print "size of c_int            : ", sizeof(c_int)
print "size of struct_1         : ", sizeof(struct_1)
print "size of my struct_2      : ", sizeof(my_struct_2)
print "siz of origional struct_2: ", sizeof(struct_2)
输出:

size of c_int            :  4
size of struct_1         :  4
size of my struct_2      :  36  
siz of origional struct_2:  34 ==> why not 36 ??
编辑:
重命名t6->t7(结构_1的数组)并从结构_2中删除pack=2。但是我仍然看到
struct_2
my_struct_2

的大小不同,这是因为在结构布局中的元素之间或之后是否存在填充,因为当大小不同时,较大的元素所占的字节数大于所有单个结构成员所需的字节数。仅成员
t5
t6
就足以证明差异,如果省略
t5
(仅限),则没有差异


一些实验表明,默认情况下(即未指定
\u pack\u
成员时),ctypes为结构类型
struct\u 1
提供2字节对齐,但为类型
c\u int
提供4字节对齐。或者在我的系统上也是这样。ctypes文档声称,默认情况下,它以与系统的C编译器(默认情况下)相同的方式布置结构,事实似乎确实如此。考虑这个C程序:

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

int main() {
    struct s {
        int16_t x;
        int8_t  y;
        uint8_t z;
    };
    struct t1 {
        int16_t  x;
        struct s y;
    };
    struct t2 {
        int16_t x;
        int     y;
    };

    printf("The size of int is       %zu\n", sizeof(int));
    printf("The size of struct s  is %zu\n", sizeof(struct s));
    printf("The size of struct t1 is %zu\n", sizeof(struct t1));
    printf("The size of struct t2 is %zu\n", sizeof(struct t2));
    printf("\nThe offset of t1.y is    %zu\n", offsetof(struct t1, y));
    printf("The offset of t2.y is    %zu\n", offsetof(struct t2, y));
}
#包括
#包括
#包括
int main(){
结构{
int16_t x;
国际会议;
uint8_t z;
};
结构t1{
int16_t x;
结构y;
};
结构t2{
int16_t x;
int-y;
};
printf(“int的大小是%zu\n”,sizeof(int));
printf(“结构s的大小为%zu\n”,sizeof(结构s));
printf(“struct t1的大小为%zu\n”,sizeof(struct t1));
printf(“结构t2的大小为%zu\n”,sizeof(结构t2));
printf(“\n t1.y的偏移量为%zu\n”,偏移量为(结构t1,y));
printf(“t2.y的偏移量为%zu\n”,偏移量为(结构t2,y));
}
它对我的输出(在CentOS 7上,在x86_64上,带有GCC 4.8)是:

int的大小是4 结构s的大小是4 结构t1的大小是6 结构t2的大小是8 t1.y的偏移量是2 t2.y的偏移量是4 注意
int
struct s
的大小是相同的(4个字节),但是编译器在
struct t1
的2字节边界上对齐
struct s
,而在
struct t2
的4字节边界上对齐
int
。这与同一系统上ctypes的行为完全匹配


至于GCC选择对齐方式的原因,我注意到,如果我将类型为
int
的成员添加到
struct s
中,那么GCC将切换到对结构使用4字节对齐方式,并(默认情况下)将结构中
int
的偏移量安排为4字节的倍数。可以合理地得出这样的结论:GCC在一个结构中布局成员,并选择整个结构的对齐方式,以便每个对齐的结构实例的所有成员都自然对齐。但是,请注意,这只是一个示例。在选择结构布局和对齐要求方面,C实现在很大程度上由它们自己决定。

这是什么语言?如果“C”使用了一些我不熟悉的扩展。在我看来像Python,而不是C。我想这是因为
struct_2
是打包的,所以
t5
之后没有填充。但是
my_struct_2
没有打包,所以
t5
t6
之间有两个字节的填充,以使其与单词对齐。顺便问一下,为什么在
struct_2
my_struct_2
中有两个
t6
成员?第二个不应该是
t7
?添加了[python](删除[memory alignment]以腾出空间),因为问题是关于python的“ctypes”module.ctypes为结构类型struct_1>>提供2字节的对齐方式,如果我显式使用u pack_u4,即使我看到不同的大小。如果我们在C代码中使用对齐和打包,那么它会给出预期的大小struct t1{int16_t x;struct s y;}属性((打包,对齐(4));int的大小是4,struct s的大小是4,struct t1的大小是8,struct t2的大小是8,t1的偏移量。y是2,t2的偏移量。y是4,我们如何在python中获得与ctypes相同的行为?pack=4不起作用。@AmitSharma,您误解了
\u pack\u
的含义。它设置最大对齐。通过将其设置为一个较小的数字,可以获得较少的填充,甚至没有填充,但不能通过将其设置为较大的数字来强制增加填充。但是,您可以通过添加一个您可以忽略的成员来手动填充结构。@AmitSharma,据我所知,ctypes没有用于指定最小对齐方式的内置机制(GCC的
\uuuuu属性的作用是((对齐))
)。 The size of int is 4 The size of struct s is 4 The size of struct t1 is 6 The size of struct t2 is 8 The offset of t1.y is 2 The offset of t2.y is 4