Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.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
PythoncTypes:将整数列表转换为短数组_Python_Python 3.x_Ctypes_Endianness - Fatal编程技术网

PythoncTypes:将整数列表转换为短数组

PythoncTypes:将整数列表转换为短数组,python,python-3.x,ctypes,endianness,Python,Python 3.x,Ctypes,Endianness,我正在尝试将一个整数列表转换为一个简短的ctypes数组。然后我想将该数组分配给bigendian结构中的一个字段。我试着这样做: from ctypes import BigEndianStructure, c_uint16 class Test(BigEndianStructure): _pack_ = 1 _fields_ = [('arr', c_uint16 * 10)] num_list = [45, 56, 23] tester = Test() short_a

我正在尝试将一个整数列表转换为一个简短的ctypes数组。然后我想将该数组分配给bigendian结构中的一个字段。我试着这样做:

from ctypes import BigEndianStructure, c_uint16

class Test(BigEndianStructure):
    _pack_ = 1
    _fields_ = [('arr', c_uint16 * 10)]

num_list = [45, 56, 23]
tester = Test()
short_array = c_uint16 * 10
tester.arr = short_array.from_buffer_copy(bytes(num_list))
但它不喜欢列表比预期的小:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    tester.arr = short_array.from_buffer_copy(bytes(num_list))
ValueError: Buffer size too small (3 instead of at least 20 bytes)
但它抱怨缓冲区不是一个“be_数组”,我认为这与endianness有关:

Traceback (most recent call last):
  File "test.py", line 14, in <module>
    tester.arr = short_array.from_buffer_copy(buffer)
TypeError: incompatible types, c_ushort_Array_10 instance instead of c_ushort_be_Array_10 instance
回溯(最近一次呼叫最后一次):
文件“test.py”,第14行,在
tester.arr=短数组。从缓冲区复制(缓冲区)
类型错误:类型不兼容,c_ushort_数组_10实例而不是c_ushort_be_数组_10实例
我是不是想得太多了?有没有人对如何解决这个问题有什么建议

编辑:根据注释的澄清,C中相应的结构有一个uint16 arr[MAX_LEN],其中MAX_LEN=10。因此,如果传递的数组不是完整的最大值,我想发送一个0填充的数组

我是不是想得太多了

是的,大量的。根本不需要从缓冲区复制
字节。如果您需要大端结构的唯一原因是您在大端系统上,那么使用常规结构将使您的生活更加轻松:

from ctypes import Structure, c_uint16

class Test(Structure):
    _pack_ = 1
    _fields_ = [('arr', c_uint16 * 10)]

num_list = [45, 56, 23]
tester = Test()
short_array = c_uint16 * 10
tester.arr = short_array(*num_list) # Or num_list[:10] if it might be too long

如果你真的想使用big-endian,即使你使用的是一个小endian系统,那么事情会变得更复杂。首先,它将导致C中的
45
56
23
变成
11520
14336
5888
。如果您不希望发生这种情况,那么您需要上述解决方案。如果这真的是你想要的,那就继续读下去。在这种情况下,
short_array=c_uint16*10
对您来说是无用的,因为它具有本机的尾端,但是您需要放入结构中的数组必须是大尾端。我不知道如何一次生成所有的大端数组类型,因此需要手动填充,如下所示:

from ctypes import BigEndianStructure, c_uint16

class Test(BigEndianStructure):
    _pack_ = 1
    _fields_ = [('arr', c_uint16 * 10)]

num_list = [45, 56, 23]
tester = Test()
for i, x in enumerate(num_list): # Or num_list[:10] if it might be too long
  tester.arr[i] = x

对bigendian结构的支持很少。您不能创建
c\u-ushort\u-be
c\u-ushort\u-be\u-Array\u 10
,但如果列表比数组短,则可以将其分配给字符串片段,这样做是正确的:

from ctypes import *
from binascii import hexlify

class Test(BigEndianStructure):
    _fields_ = [('arr', c_uint16 * 10)]

num_list = [45, 56, 23]
tester = Test()
tester.arr[:len(num_list)] = num_list
print(hexlify(bytes(tester)))
输出(原始结构的十六进制表示):


另请参见模块。它可能适合您的需要。

为了澄清,您希望的输出是否为C
uint16\u t arr[10]={45,56,23,0,0,0,0,0,0}?(当然,假设你在一个大端系统上)是的,这是正确的。C中相应的结构有一个uint16_t arr[MAX_LEN],其中MAX_LEN=10。因此,我认为如果传递的数组不是完整的MAX_LEN,它将获得一个0填充的数组。谢谢!这就是我要找的。我知道这比我现在做的要容易。它也适用于一个小的endianstructure,这是很好的了解。谢谢,你的第二个例子是我想要的更多,因为我需要的是bigendian结构,而不是原生endianness。
from ctypes import *
from binascii import hexlify

class Test(BigEndianStructure):
    _fields_ = [('arr', c_uint16 * 10)]

num_list = [45, 56, 23]
tester = Test()
tester.arr[:len(num_list)] = num_list
print(hexlify(bytes(tester)))
b'002d003800170000000000000000000000000000'