Создание memcpy из всей структуры - это действительно зло :-). Прежде всего, данные могут быть выровнены по-разному в зависимости от архитектуры. Что, если архитектура отличается с другой стороны? Также использование таких ключевых слов, как __packed, не переносимо между различными компиляторами.
Лучшее, насколько я знаю, это использовать такой API, как PHP pack / unpack. Это делает код действительно переносимым без использования специфических для компилятора уродливых ключевых слов, таких как __packed.
Я не нашел в сети ни одного пакета / распаковки для C, поэтому я написал свой собственный.
Например, чтобы распаковать два слова из двоичных данных:
pbuf_unpack(p_bts, "ww", &hdr, &ver);
Где
p_bts is binary data
"ww" describes the data structure
hdr and ver is where to put the datause an API like the PHP pack/unpack.
Еще один более обширный пример:
pbuf_unpack(p_entry, "bbbbbbbbww",
&atrb_mbr.def_boot_par, &atrb_mbr.head_start, &atrb_mbr.sec_start,
&atrb_mbr.cyl_start, &atrb_mbr.type, &atrb_mbr.head_end,
&atrb_mbr.sec_end, &atrb_mbr.cyl_end, &atrb_mbr.start_sec_pbr,
&atrb_mbr.sec_per_par);
Упаковка очень проста:
pbuf_pack(boot_buf, "sdsdhbhbhhbhhhwwbbbwsdsd", sizeof(fat_jmp_boot_t),
boot.jmp, sizeof(fat_oem_nm_t), boot.oem_nm, boot.n_bps, boot.n_spc,
boot.n_rs, boot.n_fs, boot.n_rde, boot.n_ts16, boot.media_des,
boot.n_fatsz16, boot.n_spt, boot.n_hds, boot.n_hs, boot.n_ts32,
boot.drv_no, boot.rsrvd1, boot.boot_sig, boot.vol_id,
sizeof(fat_vol_lbl_t), boot.lbl, sizeof(fat_vol_type_t), boot.type);
Он не только создает переносимый код, но и красив;)