需要联合结构的帮助。我正在接收包含各种数据包的字节流,所以我将字节数据放入联合结构中,并通过结构成员访问所需的数据。问题在于uint32_t类型的成员 - 读取通过其成员访问时跳过其两个字节并显示错误的值。下面是完整的演示代码:联合结构:打印类型为uint32_t的结构成员跳过两个字节并输出错误值
PacketUtils.h
#include <stdint.h>
typedef struct {
uint8_t startSymbol;
uint8_t packetType;
uint32_t deviceId;
uint16_t packetCRC;
} PacketData;
typedef union {
uint8_t *bytes; // stores raw bytes
PacketData *packet;
} Packet;
// Puts bytes into predefined struct
void getPacketFromBytes(void *bytes, Packet *packetRef);
PacketUtils.c
#include <stdio.h>
#include "UnionStruct.h"
void getPacketFromBytes(void *bytes, Packet *packetRef)
{
uint8_t *rawBytes = (uint8_t *)bytes;
packetRef->bytes = rawBytes;
}
调用代码:
// sample byte data
uint8_t packetBytes[] = {0x11, 0x02, 0x01, 0x01, 0x01, 0x03, 0xbb, 0xbd};
Packet packetRef;
getPacketFromBytes(packetBytes, &packetRef);
printf("%x\n", packetRef.packet->startSymbol); // good - prints 0x11
printf("%x\n", packetRef.packet->packetType); // good - prints 0x02
printf("%x\n", packetRef.packet->deviceId); // bad - prints bd bb 03 01
printf("%x\n", packetRef.packet->packetCRC); // bad - prints 36 80 (some next values in memory)
一切都OK时,分组数据结构包括uint8_t或uint16_t的类型成员然后打印显示正确的值。但是,打印uint32_t类型的deviceId将跳过两个字节(0x01 0x01)并获取最后4个字节。打印packetCRC打印给定字节数组的值 - 内存中的一些值,如packetBytes [12]和packetBytes [13]。我不知道为什么它会跳过两个字节...
谢谢。我正在编写c函数以便在iOS和Android平台上重用它。但是,iOS的Xcode目前使用LLVM编译器,Android使用GCC。 LLVM中的数据包结构语法不同,但尚未尝试,但我们需要使用< >符号进行换行。在这种情况下恕我直言代码将不可移植... – Centurion
gcc引入__attribute __((packed))语言扩展,但似乎llvm-clang也采用了它。在“Clang Language Extension”中,它说:“除了这里列出的语言扩展外,Clang还希望支持广泛的GCC扩展。”我会试试看。 –
我已经这样做了,但是,在上面的代码示例中,我在Xcode中获得了“'packed'属性忽略”警告。我正在使用Xcode 4.5.1 for iOS,它使用Apple LLVM 4.1编译器。 – Centurion