为什么当我使用双精度时,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?

本文关键字:字节 读取 我的 不正确 存储 uint32 Matlab 双精度 Qt 为什么 gt      更新时间:2023-10-16

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

我尝试了多种数据类型(int, unsigned int, float, int32_t(,但它们似乎都没有写入m_tx_data.myBytes[]中的正确字节。

我的猜测要么是我的代码中有些错误,要么 Matlab 和 Qt 读/写字节到 ints 的方式不同,我找不到怎么做。

我定义的联合

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 将返回类似的结果(。我希望m_tx_data.myBytes[58:61](0 0 0 1)(1 0 0 0)(字节序(,但它返回的是(0 0 1 0),它被 Matlab(小端序(读作65536

但是,对于我的双打,他们正在按预期保存和阅读。m_tx_data.myBytes[0:7] = (0 0 0 0 0 0 240 63)当被 Matlab 转换为双倍时,它被解读为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