2012-05-25 36 views
1

我正在研究Windows和Linux的EBDS协议接口。我试图将协议所需的所有数据打包到结构中,然后将结构本身和所有其他东西写入串行端口,并将其发送到设备。为什么enum与Windows中的位字段不兼容?

该协议的第一部分是数据封装和封装的部件中的一个是控制字节即配衬这样的描述:

Bit 0: Acknowledgement bit (switchs between 0 and 1 in each send). 
Bit 1 to 3: Device Type. 
Bit 4 to 6: Message Type. 
Bit 7: Unused. 

为了处理TIS控制字节我创建了两个枚举和一个结构:

enum E_DEVICE_TYPE 
{ 
    E_BILL_ACCEPTOR_WITH_SINGLE_ESCROW = 0x0, // 000 
    E_RESERVED_1 = 0x1, // 001 
    E_RESERVED_2 = 0x2, // 010 
    E_RESERVED_3 = 0x3, // 011 
    E_RESERVED_4 = 0x4, // 100 
    E_RESERVED_5 = 0x5, // 101 
    E_RESERVED_6 = 0x6, // 110 
    E_RESERVED_7 = 0x7, 
}; 

enum E_MESSAGE_TYPE 
{ 
    E_RESERVED = 0x0, 
    E_STANDARD_OMNIBUS_COMMAND = 0x1, 
    E_NOT_USED = 0x2, 
    E_OMNIBUS_WITH_BOOKMARK_MODE = 0x3, 
    E_CALIBRATE_REQUEST = 0x4, 
    E_FIRMWARE_DOWNLOAD_REQUEST = 0x5, 
    E_AUXILIARY_COMMAND_REQUEST = 0x6, 
    E_EXTENDED_COMMANDS = 0x7, 
}; 

#ifndef LINUX 
#pragma pack(1) 
#endif 
struct sControlByte 
{ 
    sControlByte(bool aAcknowledgeFlag, E_DEVICE_TYPE aDeviceType, E_MESSAGE_TYPE aMessageType); 

    const bool mACK : 1; 
    const E_DEVICE_TYPE mDevice : 3; 
    const E_MESSAGE_TYPE mMessageType : 3; 
    const bool mUnused : 1; 
#ifdef LINUX 
}__attribute__((packed)); 
#else 
}; 
#endif 

当我问sControlByte的大小结构的值等于6的Windows编译(Visual Studio 2010中),但在Linux(使用gcc 4.2.3)的结构的大小为1,符合市场预期。

我试图摆脱两个平台上所需属性的对齐方式,但我不知道我错过了什么¿为什么尺寸会根据平台而变化? ¿我正在使用正确的属性来控制对齐?

在此先感谢。

+2

VS编译器也有pack()编译指示,所以你不需要ifndef它。 –

+0

@Directry ifndef LINUX允许pack()_only_用于MSVC,所以你绝对需要它。 – harper

+0

@harper你说得对,我忽略了它。 –

回答

4

C++标准并未指定如何精确布置位字段。许多编译器会为每个位字段组件使用常规整数,这意味着处理速度更快,但结构更大,除非您指定了您在Linux中完成的不同首选项。

请参阅here VS2010使用的算法。

编辑:您的代码存在问题。请记住,使用带符号的基本类型,位字段的一位将被符号位使用。并且您的枚举(像大多数人一样)可能会被签名(无论它们是否是实现定义的),因此当您将E_EXTENDED_COMMANDS存储在mMessageType中时可能会看到意外,并立即发现的值不存在

有了最近的编译器,你可以force the enums to be unsigned并避免这个问题。

+0

好奇,我认为,由于涉及位字段,该字段的基本类型对于使用代码而不是大小的另一件事无关紧要。 –

+1

@PaperBirdMaster - 确实如此。然而,当它们未被打包时,访问比特字段的组件通常更快,因为那么不需要在代码生成级别上不同地移位和掩盖相邻字段。顺便说一句,我刚刚注意到你的结构可能根本无法在某些平台上工作,请参阅编辑答案。 –

相关问题