将 QByteArray 中的数据放入结构中

Bas*_* An 3 c++ arrays qt data-structures

我正在使用返回字节数组的串行设备。该数组中的值存储在无符号短整型和无符号字符中。我有以下结构:

    typedef struct {
    unsigned short RPM;             //0
    unsigned short Intakepress;     //1
    unsigned short PressureV;       //2
    unsigned short ThrottleV;       //3
    unsigned short Primaryinp;      //4
    unsigned short Fuelc;           //5
    unsigned char Leadingign;       //6
    unsigned char Trailingign;      //7
    unsigned char Fueltemp;         //8
    unsigned char Moilp;            //9
    unsigned char Boosttp;          //10
    unsigned char Boostwg;          //11
    unsigned char Watertemp;        //12
    unsigned char Intaketemp;       //13
    unsigned char Knock;            //14
    unsigned char BatteryV;         //15
    unsigned short Speed;           //16
    unsigned short Iscvduty;        //17
    unsigned char O2volt;           //18
    unsigned char na1;              //19
    unsigned short Secinjpulse;     //20
    unsigned char na2;              //21
} fc_adv_info_t;
Run Code Online (Sandbox Code Playgroud)

将数组映射到该结构的最佳方法是什么?从串行设备接收到的数组中的顺序与结构匹配。

Rei*_*ica 5

首先,您使用类 C 语法对结构中数据类型的描述是不明确的。short它没有告诉我们有关 a或类型的大小char,也没有告诉我们数据的字节序!Ashort int不一定是 16 位宽,也不一定是char8 位!至少,您应该使用固定宽度整数类型或它们的 Qt 等效项,并指定它们的字节顺序。

另外,typedef struct它是 C-ism,在 C++ 中是不必要的。放下typedef.

假设有一个大字节序数据包,unsigned short对于meanuint16_tunsigned chartomean uint8_t,你可以这样做:

struct FcAdvInfo { // this structure shouldn't be packed or anything like that!
  quint16 RPM;
  quint16 IntakePress;
  ...
  quint8 LeadingIgn;
  ...

  FcAdvInfo parse(const QByteArray &);
};

FcAdvInfo FcAdvInfo::parse(const QByteArray & src) {
  FcAdvInfo p;
  QDataStream ds(src);
  ds.setByteOrder(QDataStream::BigEndian);
  ds
    >> p.RPM
    >> p.IntakePress
    ...
    >> p.LeadingIgn
    ...
    ;
  return p;
}
Run Code Online (Sandbox Code Playgroud)

最后,如果您struct来自某些 C 代码,您必须明白它是不可移植的,即使在相同的 CPU 上,如果您升级编译器,结构类型的打包和大小也可能会发生变化!所以不要这样做。AC/C++struct声明没有暗示数据在内存中的排列方式,除了所选的排列不会导致未定义的行为,并且必须符合标准的其他要求(只有少数)。就这样,差不多了。