Temat: Pytanie
Definiując strukturę, która będzie zapisywana binarnie (a o tym mówimy) trzeba jej definicję poprzedzić #pragma pack 1 (a potem przywrócić odpowiednie pakowanie!).
Czyli w tym przypadku zarówno 'cos', 'costam' jak i 'ramka', wszystko opakować #pragma pack, oraz oczywiście używać wyłącznie zmiennych o stałej wielkości, np char, lub __int64, nigdy int który miewa różną wielkość na różnych maszynach.
Nie wiem jak z przenośnością #pragma pack, na MSVC działa doskonale. Rzuć też okiem na align.
Tzn to jest podejście w stylu C, zorganizować pamięć tak by dało się ją zapisać jednym rzutem.
Drugie podejście to w stylu C++ lub też języków wysokopoziomowych.
Każdej strukturze dodajesz metody typu
Serialize(unsigned char* aBuf, int aBufferSize) i
Deserialize(unsigned char* aBuf, int aBufferSize).
Wtedy strukturka sobie ładnie zapisuje (wczytuje) swoje proste dane, bajt po bajcie, ze wszysktimi konwersjami, zmianami endianess itd a następnie każe się tak samo zapisać swoim memberom które same są skomplikowanymi klasami/strukturami.
Podejście pierwsze jest super szybkie w zapisie i odczycie, niestety w działaniu _może_ być wolne. Po to są packi i aligny by dane leżały na wygodnych dla procesora miejscach, jak je upakujesz bez odstępów to sięganie do nich _może być_ bardziej skomplikowane.
No i jak jest tam jakikolwiek pointer, to już nie działa.
Podejście drugie jest wolne w zapisie i odczycie, za to ma praktycznie nieograniczoną elastyczność, umożliwia współpracę zupełnie różnych maszyn, (np big-endian ze small), zapisywanie tylko istotnych danych a odrzucanie śmieci a także zapisywanie memberów przechowywanych jako pointery, także polimorficznych.
Moja rada - jeśli to co piszesz służy do komunikacji pomiędzy takimi samymi maszynami, to zlej wszystko i zapisz jak Jakub napisał na początku. Wszystkie dane i dziury będą ułożone tak samo, więc trafią z powrotem w te same miejsca.
Szymon Kubisiak edytował(a) ten post dnia 21.12.09 o godzinie 11:45