Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.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 bigendianstruct littledianstruct为单个字节返回不同的结果_Python_Ctypes_Endianness - Fatal编程技术网

Python ctypes bigendianstruct littledianstruct为单个字节返回不同的结果

Python ctypes bigendianstruct littledianstruct为单个字节返回不同的结果,python,ctypes,endianness,Python,Ctypes,Endianness,当使用具有大尾数和小尾数类型的CType和结构,以及具有特定位长度的字段时,我看到了不同的结果。我希望字节中的位顺序对于两个端点都是相同的,但结果提供了不同的答案。结果来自英特尔机箱上的centos 6.8 64位发行版 >>> import ctypes >>> >>> class header_struct(ctypes.Structure): ... _fields_ = [ ('f1',ctypes.c_ubyte,4),

当使用具有大尾数和小尾数类型的CType和结构,以及具有特定位长度的字段时,我看到了不同的结果。我希望字节中的位顺序对于两个端点都是相同的,但结果提供了不同的答案。结果来自英特尔机箱上的centos 6.8 64位发行版

>>> import ctypes
>>>
>>> class header_struct(ctypes.Structure):
...       _fields_ = [ ('f1',ctypes.c_ubyte,4),
...                    ('f2',ctypes.c_ubyte,4) ]
...
>>> class header_struct_be(ctypes.BigEndianStructure):
...       _fields_ = [ ('f1',ctypes.c_ubyte,4),
...                    ('f2',ctypes.c_ubyte,4) ]
...
>>> class header_struct_le(ctypes.LittleEndianStructure):
...       _fields_ = [ ('f1',ctypes.c_ubyte,4),
...                    ('f2',ctypes.c_ubyte,4) ]
...
>>> a='\x0A'
>>> x=header_struct.from_buffer_copy(a)
>>> x_be=header_struct_be.from_buffer_copy(a)
>>> x_le=header_struct_le.from_buffer_copy(a)
>>>
>>> print " sizeof(x) ", ctypes.sizeof(x)
 sizeof(x)  1
>>> print " sizeof(x_be) ", ctypes.sizeof(x_be)
 sizeof(x_be)  1
>>> print " sizeof(x_le) ", ctypes.sizeof(x_le)
 sizeof(x_le)  1
>>>
>>> x.f1
10
>>> x_be.f1
0
>>> x_le.f1
10
>>>
>>>
>>> x.f2
0
>>> x_be.f2
10
>>> x_le.f2
0
>>>

一个字节内的位顺序对于两个字节都是不同的——当然,在任何体系结构中,你把一个数字复制到一个字节中,你会得到相同的字节。在这两种体系结构中,最低有效位被寻址为位“0”。由于数据是以字节为单位移动的,这只是模拟,所以这些位值实际上并没有在内存中的x86体系结构中镜像。这对于wat C类型是有效的,并且很可能是您将生成的C代码

但是,如果在字段中细分一个字节,则这些字段的相对位置会在字节内镜像-

您可以使用
ctypes.Union
构造以更简单的方式检查(这样您还可以排除填充字节的副作用,这可能是您看到的数字的原因):

在交互式控制台上:

In [319]: u = Union()

In [320]: u.le.value = 0x80

In [321]: u.be.value  # not mirrored
Out[321]: 128

In [322]: u.lebits.b7 
Out[322]: 1

In [323]: u.lebits.b0
Out[323]: 0

In [324]: u.bebits.b7
Out[324]: 0

In [325]: u.bebits.b0
Out[325]: 1
考虑到您可能正在编写一些实用的代码,而不仅仅是玩游戏,我的建议是将所有必须处理子字节字段的结构保持为LittleEndianStructure,并创建一个具有相同字节大小的Bigendian结构的并集,以便在需要从缓冲区复制字节来执行I/O时使用

换一种方式来说,只是为了确保清楚:所有子字节位的管理都是在声明为LittleEndian的结构上执行的。然后,要将多字节数据复制到此结构和从该结构复制多字节数据,请将其与另一个结构合并,该结构只包含具有整数字节数的字段(可以声明为BigEndian),并执行引用此另一个结构的所有数据复制


另外,对整个过程进行大量测试:-)

嗯,这确实是不直观的结果,我想知道是谁否决了这个问题。
In [319]: u = Union()

In [320]: u.le.value = 0x80

In [321]: u.be.value  # not mirrored
Out[321]: 128

In [322]: u.lebits.b7 
Out[322]: 1

In [323]: u.lebits.b0
Out[323]: 0

In [324]: u.bebits.b7
Out[324]: 0

In [325]: u.bebits.b0
Out[325]: 1