在C中将无符号短数组转换为字节数组
Posted
技术标签:
【中文标题】在C中将无符号短数组转换为字节数组【英文标题】:Converting unsigned short array to byte array in C 【发布时间】:2018-05-26 21:07:03 【问题描述】:我想将一个无符号短裤的原始数组转换为一个字节数组,然后将其读回。目的是通过 SPI 缓冲区发送数据并在另一端读取。
例子:
发件人:
unsigned short array[10] = 65000, 0, 6000, 15000, 100, 50, 1000, 10, 5000, 2000;
const uint8_t *data = charArrayToByteArray(array); // <-- convert it ?
send(data, sizeof(data)); // send it
接收者:
uint8_t buf[10];
uint8_t len = sizeof(buf);
receive(buf, &len);
unsigned short array[10] = arrayByteToCharArray(buf); // convert it back ?
工作功能:
send(const uint8_t* data, uint8_t len); //function that sends the data
receive(uint8_t* buf, uint8_t* len); // function that receives the data
我需要charArrayToByteArray()
和arrayByteToCharArray()
方面的帮助,而且数据大小不能受到影响。
谢谢!
【问题讨论】:
使用位移和掩码。unsigned char low_byte = ushort & 0xff; unsigned char high_byte = (ushort >> 8) & 0xff;
在这些数组类型之间“转换”对您意味着什么?因为最简单的事情就是读取原始数组的字节,将它们传输到接收器,并让接收器将它们解释为短整数。只要发送方和接收方使用unsigned short
的相同表示,这将正常工作(这是一个不可忽略的考虑因素)。除了几个指针转换之外,不需要特殊的转换。
是的,将其读入缓冲区是可以的,但我并没有找到任何关于如何使用数组执行此操作并将其读回的信息。
顺便说一句,在您的 send()
和 receive()
函数中将 len
设为 uint8_t
类型意味着您将永远无法在一次调用中发送或接收超过 255 个字节,这似乎有点限制。如果您有能力更改它,您可能希望将其更改为 uint32_t
。
【参考方案1】:
由于您的数组包含无法作为单个字节发送的值(如 65000),因此假设您打算将每个值作为两个字节发送是合理的。
鉴于此,数据值根本不需要转换;而只是指针的类型(以便send()
调用将编译)。所以这应该足够了:
unsigned short array[10] = 65000, 0, 6000, 15000, 100, 50, 1000, 10, 5000, 2000;
const uint8_t *data = reinterpret_cast<const uint8_t *>(array);
send(data, sizeof(array));
注意send()
调用指定sizeof(array)
而不是sizeof(data)
;因为data
是一个指针,它的大小是4字节或8字节(取决于你的CPU架构),与你要发送的数据字节数无关!
接收端类似:
uint16_t buf[10];
uint8_t len = sizeof(buf);
uint8_t * data = reinterpret_cast<uint8_t *>(buf);
receive(data, &len);
注意receive()
返回后,len
会表示接收到的bytes个数,所以接收到的uint16_t
值的个数将是那个的一半:
int numShortsReceived = len/sizeof(uint16_t);
for (int i=0; i<numShortsReceived; i++) printf("Received short #%i = %u\n", i, buf[i]);
另一个注意事项:上面的代码不处理大端/小端转换。如果您可以保证发送方和接收方都将在具有相同字节序的 CPU 上运行,那不是问题。如果 OTOH 您需要此代码在混合 CPU 上正常工作(即,大端发送器发送到小端接收器,反之亦然),那么您需要让您的发送代码转换您的每个uint16_t
's 到 network/big-endian 在发送它们之前(通过htons()
)并让您的接收代码将每个接收到的uint16_t
's 从 network/big-endian 转换为其本地 endian-ness(通过ntohs()
) 在收到它们之后(但在尝试将它们用于任何事情之前)。
【讨论】:
感谢您的回答,它确实解释了发送/接收部分。但我不知道如何使用位移来获取 uint16_t 数组。我得到奇怪的价值观。 for 循环中的示例:shortArray[i] = (data[i] << 8) | (data[i+1]);
我的错,应该是shortArray[i] = (data[I*2 + 1] << 8) | (data[i*2]);
不需要移位;字节的格式已经正确。以上是关于在C中将无符号短数组转换为字节数组的主要内容,如果未能解决你的问题,请参考以下文章