我正在尝试为CAN通信通道创建一个11位ID字段。我想我应该可以使用:
import ctypes
class ID(ctypes.Union):
_fields_ = [('device', ctypes.c_int, 3), # 3 bits for device id
('message', ctypes.c_int, 8)] # 8 bits for message ID
当我尝试验证此类的实例是我想要的时,会发生什么问题。具体做法是:
>>> x = ID()
>>> type(x.device)
<type 'int'>
为什么是int而不是c_int?同样地:
>>> x = ID()
>>> x.device.bit_length()
0
这正是我不想要的。
编辑:
感谢您的帮助!我绝对应该使用结构。
我正在尝试创建一个表示CAN data frame的标识符和数据部分的对象。我正在使用的约定进一步将标识符帧分成3和8位段,分别代表设备和消息ID。我想要的是一个表示标识符框架的类,我可以在其中为与我的约定设备和消息ID相对应的成员分配值,并将其序列化为11位ID值。
也许我需要再看看我用于CAN通道的C库 - 可能是我可以使用16位结构,其中我只使用11位。
答案 0 :(得分:2)
在Union
内,device
成员使用8位存储。
但是,ctypes
会自动为您转换为原生int
类型,使用(很好的近似)通常的C规则来转换类型。例如,试试这个:
>>> x.device = 257
>>> x.device
1
所以,你在这里没有任何问题需要解决。
但是,做有问题:
我正在尝试为CAN通信通道创建一个11位ID字段。
8位int的Union
和3位int是8位,就像在C中一样。你想要一个Struct
。有关详细信息,请参阅Structures and unions以及从那里链接的类型参考。
除此之外,虽然3位int和8位int的Struct
只有11位有用信息,但它几乎肯定占用至少16位内存,其中5位填充位。*一次只能对一个字节(8位)的内存进行寻址。所以...我不确定你要对这个ID做什么,但我怀疑它不会起作用。如果你解释your actual problem,理想情况下是complete sample code,我们可以提供帮助。
*实际上,至少在当前的CPython版本中,它实际上占用了32位内存。有关详细信息,请参阅eryksun的评论。