Piszę prosty binarny serializatorgeneruj pliki zapisu dla 64-bitowej gry wideo przeznaczonej dla 64-bitowych platform Windows, Mac i Linux. Typy zmiennych wybrane do serializacji to: char, short, bool, unsigned int, int, float, ewentualnie double i ewentualnie long int. Kompiluję na Visual Studio. Serializacja jest tak prosta, jak to możliwe, bez sprawdzania, wystarczy proste zapisanie danych binarnych, a następnie deserializacja danych w tej samej kolejności. Gra bardzo często zapisuje nowe dane w pliku podczas gry, ale dane są przekształcane w postaci szeregowej tylko raz, tuż przed rozpoczęciem gry.
Nie sądziłem, że przenośność jest czymśże musiałem się martwić prostą funkcją zapisywania gry; czytałem jednak o wielu problemach związanych z przenośnością związanych z serializacją binarną (np. reprezentacja zmiennoprzecinkowa, różnice w szerokości bitowej liczb całkowitych, endianowość, wyrównanie itp.) i nie jestem wystarczająco pewny swojego zrozumienia tematu, aby być pewnym że te problemy z przenośnością nie odwrócą głowy w tym projekcie. Być może ktoś byłby tak uprzejmy, aby podzielić się pewną perspektywą na temat następujących założeń:
- Zmienne mogą być serializowane do pliku binarnego na jednym komputerze i w pliku plik binarny może być następnie skopiowany i bezpiecznie deserializowany na inna maszyna z tym samym systemem operacyjnym i procesorem x86-64.
- Jeśli założę, że wszystkie maszyny z systememgra to procesory w stylu little-endian x86-64 z 64-bitowymi systemami operacyjnymi, czy mogę założyć, że plik binarny może być w pełni przenośny między systemy operacyjne też?
- Gdybym miał rozszerzyć program do obsługi32-bitowa wersja gry (wciąż zakładając architekturę procesora x86-64 na komputerze docelowym platforma, ale 32-bitowy system operacyjny) i decyduje o tym 32-bitowy użytkownik końcowy uaktualnić do 64-bitowego systemu operacyjnego, instaluje 64-bitową wersję gry i następnie ładuje swój stary plik zapisu, który został zserializowany w wersji 32-bitowej System operacyjny z 32-bitową wersją gry - może te typy zmiennych następnie można bezpiecznie dokonać deserializacji na platformie 64-bitowej w kolejności w które zostały zserializowane bez żadnych kontroli ani testów zgodność?
Czy jest możliwe, że zapisanie na jednym komputerze i załadowanie na innym może uszkodzić dane w którymkolwiek z tych scenariuszy?
Z góry bardzo dziękuję.
Odpowiedzi:
1 dla odpowiedzi № 1Jeśli używasz typów liczb całkowitych o rozmiarze, takich jak ::std::uint32_t
zamiast niejasnych typów, takich jak unsigned long
wtedy będziesz prawie oszczędzać od liczby całkowitejróżnice wielkości, które mogą wystąpić między platformami 32-bitowymi / 64-bitowymi i różnymi kompilatorami. Całkowita liczba bitów może się różnić technicznie, ale tylko na dość egzotycznych platformach, których zdecydowanie nie można uznać za odpowiednie do grania. Rozmiar zmiennoprzecinkowy i reprezentacja również nie powinny stanowić problemu.
Aby upewnić się, że rozmiar i wyrównanie struktur danych odczytywanych / zapisywanych pozostaje spójny na różnych platformach, których należy użyć static_assert
w tobie kod.
Jednak sprawdzenie endianizmu jest obowiązkowechcesz, aby twoje zapisane pliki były przenośne. Zazwyczaj możesz chcieć serializować dane przy użyciu natywnego endianizmu i zapisać na początku pliku magiczną liczbę wskazującą jego endianizm (np. 0x01020304
). Następnie, kiedy deserializujesz, najpierw sprawdź tę magię i wybierz albo natywny deserializator endianizmu (który jest szybszy), albo odwrócony deserializator endianizmu (który jest wolniejszy).