Python ctypes到np.D类型位域转换

2024-10-03 04:28:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我从一个服务器接收到一个bytestring,我正试图解码。我已经找到了ctypes结构(参见代码),但它包含位字段。在

我通常只是用np.frombuffer函数获取数据,因为它可以识别大多数ctypes。另外,我可以将数据写入HDF5文件,而不需要任何操作。但是,由于位字段的原因,dtype大小和ctype大小不匹配,因此数据被转换,但显然是错误的。您应该能够按原样运行下面的代码。在

import ctypes
import numpy as np

#%%
class SubStruct(ctypes.Structure):
    _pack_ = 1
    _fields_ = [('bUnderrange', ctypes.c_ubyte, 1),
                ('bOverrange', ctypes.c_ubyte, 1),
                ('bLimit_1a', ctypes.c_ubyte, 1),
                ('bLimit_1b', ctypes.c_ubyte, 1),
                ('bLimit_2a', ctypes.c_ubyte, 1),
                ('bLimit_2b', ctypes.c_ubyte, 1),
                ('bError', ctypes.c_ubyte, 1),
                ('TXPDO', ctypes.c_ubyte)] #This is a byte, rest are bits

class MainStruct(ctypes.Structure):
    _pack_ = 4
    _fields_ = [('stStatus', SubStruct),
                ('nValue', ctypes.c_ushort),
                ('fValue', ctypes.c_float)]

rawdata = b'X\x00W\x00ff\x86AV\x00\xd6\x0033{B\n\x00-\x00ff\x9aAW\x00\xc8\x01ff\nB'

#%%
a = SubStruct()
b = MainStruct()

print('Data size: ',len(rawdata))
print('\nSubStruct:')
print('Ctype size: ',ctypes.sizeof(a))
print('Dtype size: ',np.dtype(a).itemsize)
print('\nMainStruct:')
print('Ctype size: ',ctypes.sizeof(b))
print('Dtype size: ',np.dtype(b).itemsize)

data = np.frombuffer(rawdata, dtype=MainStruct) #WRONG

我期望的是:

^{pr2}$

我得到的是:

^{3}$

当ctype可用时,有没有一种有效的方法来获得正确的数据类型?或者一种有效地操作rawdata的方法,这样我仍然可以应用np.frombuffer功能?在


Tags: 数据代码sizenpctypectypesprintdtype
1条回答
网友
1楼 · 发布于 2024-10-03 04:28:50

从numpy 1.16(#12254)起,这将返回一个错误,而不是生成错误的结果:

>>> data = np.frombuffer(rawdata, dtype=MainStruct)
TypeError: ctypes bitfields have no dtype equivalent

NumPy不支持位域,因此无法使其工作。最好的办法是定义一个不包含位域的替换类型,并使用它。在

如果你在将来看到类似这样的错误行为,我强烈建议你在NumPy问题跟踪器上报告,尤其是考虑到你所拥有的最少的例子。在

相关问题 更多 >