В общем, если вы хотите разумного результата, нет.
Это связано с тем, что CRC предполагается вычислять по последовательности «известных» байтов, а структура в памяти - , а не - последовательность известных байтов. Для выравнивания могут быть байты заполнения, о которых вы не всегда знаете или имеете контроль, и, конечно, различные поля могут иметь различные размеры (как и сам struct
) на разных системах/платформах.
Если вы сначала можете сериализовать структуру в последовательность байтов с известным и стабильным отображением, тогда, конечно, вы можете применить CRC к этой последовательности. Это (тонко) намечено аргументом buffer
, равным const u8 *
, то есть указателем на постоянный байт, а не const void *
.
Если вы не заботитесь, а не против разрыва, если (например) изменить настройки компилятора и/или переместить программу в другую систему, вы могли бы просто использовать:
const struct mystruct s = { ... };
const u16 crc = crc16(0, (u8 *) &s, sizeof s);
Но этот будет содержать любые дополнения в структуре, поэтому это очень опасно.
Вы можете применить указатель к структуре: 'struct any x; crc16 (crc, (u8 const *) & x, sizeof (struct whatever)); ' –
Вы можете столкнуться с некоторыми проблемами, если полагаетесь на CRC как один и тот же кросс-компилятор (по крайней мере), (например, заполнение структуры) –
@ Джонни Мопп дал ответ, но есть недостаток: «Заполнение». Структура может содержать добавку, вставленную компилятором, значение прокладки неопределенно, но будет использоваться при вычислении контрольной суммы. Рекомендуется явно установить всю структуру в ноль с помощью 'memset' до инициализации. В противном случае две иначе идентичные структуры могут создавать разные контрольные суммы. –