Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

17.06.2014, 17:41

Binäre Dateien Hardwareunabhängig schreiben und lesen?

Hallo,

hab schon wieder eine Frage, diesmal bezüglich dem schreiben und lesen von binär Daten.
An sich ist das ganze ja kein Problem, dass Problem tritt erst in meinem Kopf auf, wenn ich daran denke
das die Größe (in Bytes) verschiedener nativer Datentypen Hardware abhängig ist.

So stellt sich mir die Frage:

Wenn ich auf meinem System ein Integer binär in eine Datei schreibe, welcher 4 Bytes misst, und dann
auf einem anderen System diese binär Datei lesen möchte, wo ein Integer allerdings 6 Bytes misst,
darf ich dann erwarten das alles schief gehen wird?

Über das Internetz kam ich zum Thema Serialisierung & Deserialisierung mit boost, nur möchte
ich in meinem kleinen bescheidenen Projekt nicht eine riesige Bibliothek verwenden, von der ich eigentlich
nur ein einziges Feature an einer einzigen Stelle brauche. Und ich möchte meine Objekte auch nicht
in XML oder sonst was darstellen sondern "nur" im Binär Format, da die Datenmengen groß sind, schnell lesbar sein sollen usw.

Deshalb wäre es in meinen Augen total übertrieben direkt boost nur dafür zu benutzen, wodurch bei mir die eigentliche Frage aufkommt:

Was hat Boost "getan" um es zu ermöglichen, dass die Binärdaten unabhängig von der Hardware lesbar sind?

Es geht mir auch gerade nicht nur um boost und das es übertrieben wäre es nur dafür zu verwenden, sondern natürlich auch
um das Interesse hinter diesem Thema. Hab nämlich auch gerade gesehen, dass man nur den Serialization Teil von boost
verwenden kann.

Vielen Dank fürs lesen und vielen Dank schon mal im Voraus für jede Erklärung. :)

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

17.06.2014, 17:52

Du musst dich halt auf eine Konvention festlegen und diese einhalten.
Z.B. kannst du festlegen, dass deine Integer 32 Bits groß sind und die Bytes im "Little Endian"-Format angeordnet sind (http://de.wikipedia.org/wiki/Byte-Reihenfolge).
In deiner Software musst du dann beim Lesen und Schreiben prüfen, ob die Hardware-Plattform deine Konvention einhält. Wenn nicht, dann musst du die Daten halt vor dem Schreiben bzw. nach dem Lesen anpassen (also beispielsweise die Bytes vertauschen).

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

3

17.06.2014, 18:01

Der Datentyp long int ist 32 bit groß, während short int 16 bit groß ist. Somit kannst du dich festlegen, egal ob int 32 oder 16 bit ist.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

17.06.2014, 18:17

Der Datentyp long int ist 32 bit groß, während short int 16 bit groß ist. Somit kannst du dich festlegen, egal ob int 32 oder 16 bit ist.

Wenn du dich auf C/C++ beziehst, dann ist das schlichtweg falsch.
Nirgendwo steht festgeschrieben, wie groß die einzelnen Datentypen genau sein müssen.

FSA

Community-Fossil

  • Private Nachricht senden

5

17.06.2014, 18:26

Zu den Datentypen: int32_t, uint32_t sind, soweit ich weiß, unter jedem Compiler und jeder Plattformg gleich groß. #include<cstdint>
http://pubs.opengroup.org/onlinepubs/009…s/stdint.h.html

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

6

17.06.2014, 18:29

Über dein Problem haben sich schon mehrere den Kopf zerbrochen ;). Und es gibt auch gute Lösungen abseits von Boost. Z.B. Protocol Buffer von Google oder Message Pack. Ich würde dir in deinem Fall raten Message Pack einmal an zu sehen und wenn es nur der Quellcode und die Doku ist um zu schauen wie es gemacht wurde.

Message Pack
Protocol Buffer
:love: := Go;

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

17.06.2014, 19:10

Zu den Datentypen: int32_t, uint32_t sind, soweit ich weiß, unter jedem Compiler und jeder Plattformg gleich groß. #include<cstdint>
http://pubs.opengroup.org/onlinepubs/009…s/stdint.h.html

Ja, aber die Byte-Reihenfolge (Endianess) ist damit immer noch nicht festgelegt.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

8

17.06.2014, 19:11

Er bezieht sich mit hoher Wahrscheinlichkeit auf C++ weil in C#/Java gibt es keinen "short int". Es gibt "int". Und es gibt "short". Aber nicht beides. Das gibt es nur bei C(++). Bei "short" trifft seine Annahme in der Praxis sogar fast immer zu, aber "long" unterscheidet sich bereits zwischen Windows und der Rest der Welt (Linux, BSD, etc). Ich empfehle ganz generell FSAs Datentypentipp. Für die Endianness-Probleme baut man sich ein paar dünne Hilfsmethoden mit Byte-Swap. Wenn man gerne mit skalierende Typen wie "std::size_t" ensetzt, muss man diese einfach auf den größten gemeinsamen Nenner casten, bevor man schreibt. (In der Regel zum Beispiel "std::uint64_t")

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (17.06.2014, 19:17)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

17.06.2014, 19:21

Natürlich bezieht er sich auf C++, aber die Endianess ist damit trotzdem noch nicht festgelegt. Genau wie die Größe des Datentyps eben je nach System oder Compiler ebenfalls variiert.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

10

17.06.2014, 19:32

Die Endianness kann man halt entweder im Programm oder in der Datei festlegen. Ich bevorzuge Letzteres. Das kann zum Bleistift so aussehen, dass man als erste Information ein Prüfwort in die fragliche Datei schreibt. Im Falle meiner VM ist das Prüfwort der 4-Byte-String 'oxbc' am Anfang der Datei. Lädt die VM als Prüfwort 'oxbc', ist die Endianness der Datei die der lokalen Maschine. Bei 'cbxo' sind Byteswaps von Nöten.
(Middle Endian wird von meiner VM nicht unterstützt.)

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Werbeanzeige