为什么当我使用 double 时 Qt<->Matlab 可以正确写入和读取我的字节,但对于存储 uint32 的字节却不正确?

Why are my bytes being written and read properly by Qt<->Matlab when I use doubles, but improperly for my bytes storing uint32?

我正在尝试通过 UDP 将数据包从我的 Qt GUI 应用程序发送到 Mathworks Simulink 模型,并在其中解包。我正在使用联合将数据保存到并将其转换为要发送的 char 字节数组。我的前 58 个字节按预期写入和读取,但最后一部分没有。

我尝试了多种数据类型 (int, unsigned int, float, int32_t),其中 none 似乎正在写入 m_tx_data.myBytes[] 中的正确字节。

我的猜测是我的代码中出现了一些小问题,或者 Matlab 和 Qt read/write 字节到整数的方式不同,但我不知道是怎么回事。

我定义的联合

const int GUI2DEVICE_NUM_DOUBLE = 7;
const int GUI2DEVICE_NUM_BOOL  = 2;
const int GUI2DEVICE_NUM_INT32 = 3;

const int GUI2DEVICE_DATA_SIZE = (GUI2DEVICE_NUM_DOUBLE*sizeof(double)) +
                                 (GUI2DEVICE_NUM_BOOL*sizeof(bool)) +
                                 (GUI2DEVICE_NUM_INT32*sizeof(unsigned int));
union GuiToDeviceDataType
{
    char myBytes[GUI2DEVICE_DATA_SIZE];
    struct
   {
      double        doub[GUI2DEVICE_NUM_DOUBLE];
      bool          boolean[GUI2DEVICE_NUM_BOOL];
      int32_t       int32[GUI2DEVICE_NUM_INT32];
    } part;
};

正在为联合赋值。每个变量都将类型匹配到它要去的结构的一部分。 m_tx_data.myBytes初始化为0。

    m_tx_data.part.doub[iAmplitude]                 = amplitude;
    m_tx_data.part.doub[iStartFrequency]            = startHz;
    m_tx_data.part.doub[iStopFrequency]             = stopHz;
    m_tx_data.part.doub[iFrequencyRampTime]         = FreqRampTime;
    m_tx_data.part.doub[iAmpRampUpTime]             = AmpRampUpTime;
    m_tx_data.part.doub[iAmpRampDownTime]           = AmpRampDownTime;
    m_tx_data.part.doub[iAutoScaleDecrementPercent] = ASDecPercent;
    m_tx_data.part.boolean[0] = 1;
    m_tx_data.part.boolean[1] = 1;
    m_tx_data.part.int32[iSweepSteps]              = SweepSteps;
    m_tx_data.part.int32[iPeriodsToAverage]        = PeriodsToAverage;
    m_tx_data.part.int32[iPeriodsToIgnore]         = PeriodsToSkip;

分配给 m_tx_data.part.int32[] 的值等于 1(将它们分配给 2 或 3 return 类似的结果)。我期望 m_tx_data.myBytes[58:61](0 0 0 1)(1 0 0 0)(字节序),但它是 returning (0 0 1 0),它被读作 65536 Matlab (little endian).

但是,对于我的双打,他们正在按预期保存和阅读。 m_tx_data.myBytes[0:7] = (0 0 0 0 0 0 240 63) 被 Matlab 转换为 double 时读作 1

调试和查看 m_tx_data.myBytes 时,我可以看到存储在每个字节中的值,并观察每个变量被写入结构。

添加检查static_assert(sizeof(GuiToDeviceDataType::part) == GUI2DEVICE_DATA_SIZE)。由于对齐,它应该在您的情况下显示错误。让我们检查一下:

size_t sz1 = sizeof(GuiToDeviceDataType::part);
// sz1 == 72 and GUI2DEVICE_DATA_SIZE is 70

重新排序结构以将 bool 字段移动到结构的末尾,这样您将获得更多预期结果 - 填充应该仅在结构的末尾。您可以通过将指针地址转换为 char* 然后显示差异来检查这一点:

        GuiToDeviceDataType data;
        size_t sz1 = sizeof(GuiToDeviceDataType::part);
        char* p1 = (char*)(void*)&data.part.boolean[0];
        char* p2 = (char*)(void*)&data.part.int32[0];
        size_t diff = p2 - p1;
        std::cout << diff; // shows 4 for your code