Эта процедура от конечного автомата для доступа к GPS через последовательный порт. Я пытаюсь приступить к работе, но он не копирует пакет отчета в структуру отчета.
Пакет отчета создается процедурой ввода-вывода, и когда пакет завершается, он передается в функцию отчета об обновлении. 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 в соответствующую структуру позволит сэкономить много кода.
Я могу заполнить структуру, если объединю целочисленный массив без знака со структурой и получу цикл для его перемещения символ за символом. Это требует изменения всех структур и, возможно, нарушения существующего кода, который мне неизвестен.
Я надеюсь, что с memcpy есть способ перейти от массива к структуре, но я заблудился, указатели были определены как void * или const void *, а затем получили место назначения в различных форматах. Я также не уверен, почему указатель dst установлен со ссылкой, а src - нет. Ссылка на memcpy не дает достаточного фона для меня, чтобы понять, что требуется.
Таким образом, грубая сила выполнит работу, но я хотел бы понять более изящное (глазами смотрящего) решение.
Окончательное обновление
Никогда не заставлял memcpy работать в этой ситуации. Но узнал несколько вещей, которые должны были быть очевидными. Самое главное, я запускаю приложение в системе с прямым порядком байтов, а поток данных поступает из системы высокого уровня. Memcpy не будет правильно форматировать многобайтовые поля. Поэтому, если memcpy будет работать, он не даст правильных результатов.
Значит, грубая сила победит.