场景:远程机器(大端)通过RS422向本地机器(小端)发送消息.
本地机器将消息作为缓冲区获取,即dataBuffer,它是4个16位整数的数组.此缓冲区数据最终会映射到程序中的某个MainType数据,但这不是我们关注的问题.我们需要一个使用swapData()方法交换字节(更改字节顺序)的函数.
问题:鉴于MainType正好有4个数据成员,每个16位AND dataBuffer是大小为4的数组,每个数据是16位,我们可以只交换缓冲区中的数据而不将其映射到MainType数据结构(如下所示)?
约束:
> dataBuffer需要在程序中是全局的,
>交换需要在swapData()函数中处理,
>数据将用其他方法填充,例如useData()
这是代码:
...
typedef unsigned short int USINT16;
typedef struct {
USINT16 a : 1;
USINT16 b : 1;
USINT16 c : 1;
USINT16 d : 1;
USINT16 e : 1;
USINT16 f : 1;
USINT16 g : 1;
USINT16 h : 2;
USINT16 i : 3;
USINT16 j : 4;
} OtherType; // 16 bits
typedef struct {
USINT16 X;
USINT16 Y;
USINT16 Z;
OtherType W;
} MainType;
...
unsigned short dataBuffer[4]; // available in global scope
...
void swapData() {
receiveData(&dataBuffer); // data buffer is filled
int i;
for (i = 0; i < 4; i++) {
dataBuffer[i] = __builtin_bswap16(dataBuffer);
}
// The data is little endian now ?
}
...
void useData() {
MainType data; // map the swapped buffer to data
// use the data etc.
....
}
最佳答案 如果远程计算机行为被冻结,您可以调查并确定该平台上的位字段的编码是什么,并适当地转换在本地计算机上接收的缓冲区.
字节交换所有16位条目(包括W)是一个很好的初始步骤,您可能必须更改OtherType的结构定义以适合远程计算机的编译器定义的顺序.您可以通过从远程计算机传输样本来确定,其中只有1个字段设置为所有位1,其他位置保持为0并打印接收到的16位值.
建议使用字节交换W,因为W.h很可能落在字节边界上,每个字节有1位.要使其在本地机器中相邻的位,应交换W中的字节.如果远程机器上的位顺序是W中的整个16位字的b c d e f g h1 h0 i2 i1 i3 j3 j2 j1 j0,当存储在远程机器的存储器中时,它变为< a b c d e f g h1> < h0 i2 i1 i0 j3 j2 j1 j0>然后作为字节传输并加载到本地机器上的16位寄存器中,如果不交换字节,它将变为h0 i2 i1 i0 j3 j2 j1 j0 abcdefg h1,因为第一个字节是在低位的位中加载的.寄存器.字节交换可以防止这种情况,但是您仍然可能在本地计算机中遇到位字段顺序问题,因为如果位字段可能从最低位分配,则当前定义可能被编码为j3 j2 j1 j0 i2 i1 i0 h1 h0 gfedcba到最高位位置.
如果您知道某种汇编语言,请生成用于操作两个平台上的位字段的代码的程序集,并检查字段的放置方式是否不同.