此例程来自状态机,用于通过串行端口访问gps。我试图开始工作,但它不会将报告数据包复制到报告结构中。
报告数据包由i / o例程构建,当数据包完成时,它将传递给更新报告功能。 m_report.report.data已正确填充,我已将其转储。但是,我无法确定如何构建通用memcpy语句以将数据复制到正确的结构。
报告包可以有三种格式,但根据代码/子代码输出到超过15种不同的结构。只复制报告或扩展结构的数据部分。
union _report_packet {
struct _raw {
UINT8 data[MAX_DATA];
} raw;
struct _report {
UINT8 code;
UINT8 data[MAX_DATA-1];
} report;
struct _extended {
UINT8 code;
UINT8 subcode;
UINT8 data[MAX_DATA-2];
} extended;
} m_report;
struct _ecef_position_s {
bool valid;
struct _0x42 {
SINGLE x; // X meters
SINGLE y; // Y meters
SINGLE z; // Z meters
SINGLE time_of_fix; // time of fix in GPS or UTC seconds
} report;
};
struct _ecef_position_d {
bool valid;
struct _0x83 {
DOUBLE x; // X meters
DOUBLE y; // Y meters
DOUBLE z; // Z meters
DOUBLE clock_bias; // clock bias meters
SINGLE time_of_fix; // time of fix in GPS or UTC seconds
} report;
};
update_report() {
void *src;
void *dst;
// save report
switch (m_report.report.code) {
case REPORT_ECEF_POSITION_S:
m_ecef_position_s.valid = true;
src = m_report.report.data;
dst = &m_ecef_position_s.report;
break;
case REPORT_ECEF_POSITION_D:
m_ecef_position_d.valid = true;
src = m_report.report.data;
dst = &m_ecef_position_d.report;
break;
.......more cases and some codes have sub-codes
}
memcpy(dst, src, std::min(m_report_length, rlen));
}
我看了几个例子,阅读手册并尝试从类似问题收集想法,但所有例子似乎都处理非常简单的POD。我只是不明白如何跨越更复杂的局面。这甚至可以用C ++完成吗?
rlen是m_report缓冲区中字节数的计数。在我的测试中,它是正确的长度,并且总是小于最大长度1024.
没有错误:这里是输入和输出区域的转储:
m_report.raw.data []: 0 3 83 c8 6 8c 0 f 3 31 3a f 15 2 7 dc 2f a9 a7
搬家后报告: f0 e 0 0 0 0 0 0 6d 79 43 4f 0 0 0 0 cb 86 e1输出区域不会改变。
我提供的是代码的简化子集。我不知道历史或它是如何产生的。大约有12个结构总共运行了近300行,因此开发一种将m_report.data移动到适当结构的方法可以节省大量代码。
如果我将无符号整数数组合并到struct并且有一个循环来逐字符地移动它,我可以填充结构。这需要修改所有结构,并可能破坏我不知道的现有代码。
我希望memcpy有一种从数组移动到结构的方法,但是我迷失了指针被定义为void *或const void *然后以各种格式使用目标。我也不确定为什么dst指针设置了引用而src不是。对memcpy的引用并没有为我提供足够的背景来掌握所需内容。
如此蛮力将完成工作,但我想了解一个更优雅(旁观者的眼睛)解决方案。
永远不会让memcpy适应这种情况。但是学到了一些应该是显而易见的事情。最关键的是,我在小端系统上运行应用程序,数据流来自高端系统。 Memcpy不会正确格式化多字节字段。因此,如果memcpy工作,它将无法给出正确的结果。
如此蛮力赢得胜利。