为什么当我使用双精度时,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
(,但它们似乎都没有写入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
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 在java中读取c++字节的位字段
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- std::ifstream::read 不会读取所有 512 字节,并设置 EOF 和失败位
- QDataStream 读取和写入的字节数比 QFile::length() 报告要多
- 如何从保存在 Java 中C++的字节数组中读取数字?
- Async_read_until限制读取的字节大小(Boost::asio)
- 如果由不同的线程写入 8 字节,那么现代英特尔 x86 上的 8 字节读取是否保证理智?
- C++ - 将任何文件的字节读取到无符号字符数组中
- InternetReadFile 填充缓冲区,但返回零字节读取
- ReadFromFile C++具有未知字节读取大小
- 从字节 [] 读取字符串
- C 如何将字节读取为整数enderness独立
- x64 CPU上的原子16字节读取
- 具有重叠I/O的FILE_FLAG_NO_BUFFERING-字节读取为零
- std::数组和字节读取
- 如何发现字节读取是日语还是英语
- 内存的字节读取:"signed char *" vs "unsigned char *"
- TCP Recv使用select()返回1字节读取
- c++字节读取问题