1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Unsere jährliche Weihnachts-Banner-Aktion hat begonnen! Wir freuen uns auf viele, viele kreative Vorschläge.
    Mehr dazu könnt Ihr hier nachlesen: Weihnachtsbanner 2016

    Information ausblenden

Big Endian sorgt für korrupte Dateien

Dieses Thema im Forum "OS X-Developer" wurde erstellt von GoaSkin, 13.09.07.

  1. GoaSkin

    GoaSkin Gast

    Ich programmiere gerade ein Programm, das dazu dienen soll, GUI-gesteuert Plugins für ein Spiel zu erzeugen und lege dabei Wert auf Plattformtransparenz.

    Ich habe mich dazu entschlossen, die QT-Bibliothek zu nutzen und XCode als Entwicklungsumgebung zu nutzen. Soweit so gut, der Quellcode lässt sich unter Windows, OSX und Linux compilieren und das Programm läuft --scheinbar-- auf allen Plattformen einwandfrei. Das dachte ich bis vor kurzem zumindest.

    Ich habe nun das Programm einmal auf einem G4 compiliert und ausgeführt und wunderte mich die ganze Zeit, daß die erzeugten Dateien korrupt sind. Nach einigen Analysen stellte ich fest, daß sämtliche Ausgabevariablen in der Datei in umgekehrter Byte-Reihenfolge zu lesen sind. Die Endian-Problematik war eine schnelle Vermutung, die sich auch bestätigte.

    In der Export-Funktion wird gemäß Spezifikation ein langer Array mit allen notwendigen Daten erzeugt und dieser anschließend in eine Datei geschrieben. PPC-Rechner schreiben alle einzelnen Variablen verkehrt herum in diesen Array rein.

    Das Netz verrät viel, mit welchen Funktionen sich Byte-Reihenfolgen umdrehen lassen, wobei ich das kaum für praktikabel halte. Unter anderem wird eine Header-Datei mit Funktionen zur Endian-Konvertierung mit dem Ziel, Netzwerkdaten umzudrehen genannt, die man auch nutzen kann, um einzelne Variabeln zu drehen. Das wäre in diesem Fall viel Arbeit, würde den Quellcode sehr unübersichtlich machen und für 64Bit-Integer müsste ich mir noch eine Lösung einfallen lassen.

    Gibt es keine Lösung (z.B. ein Makro), mit der man im Quelltext nicht permanent darauf achten muß, daß ein PPC im Big-Endian-Modus arbeitet und dafür sorgt, daß einzelne Werte grundsätzlich so in einen Array eingetragen werden, als wäre es eine Little-Endian-Maschine?

    Da ja ein PPC angeblich auch den Little-Endian-Modus beherrscht - gäbe es ggf. die Möglichkeit, dafür zu sorgen, daß das Programm im Little-Endian-Modus läuft?
    Unter Linux (PPC) kann man das gcc-Flag -m little setzen. Unter Darwin kennt der GCC das nicht.
     
  2. below

    below Kalterer Böhmer

    Dabei seit:
    08.10.06
    Beiträge:
    2.865
  3. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.245
    Wenn Du ständig Werte in Arbeitsspeicher in der falschen Reihenfolge ablegst ist die Performance unterirdisch. Füge eine saubere Serialisierungsschicht in die Software ein, so daß das kein Problem mehr ist.
    Das wurde vom OS vorgegeben, und außer NT hat es nie ein OS auf PPC genutzt. Die neuen PPCs kann man zum Teil nur noch im BigEndian Modus betreiben.
     
  4. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Nein, die gesamte Zeit in der nicht-nativen Byte-Reihenfolge zu arbeiten, wäre dämlich. Vor dem Schreiben gleich eine swap-feste Library zu verwenden, oder falls es die nicht gibt, wie von tjp vorgeschlagen selbst eine Schicht dazwischen einzuführen, ist nicht unübersichtlich. Sie ist sogar transparent, also unsichtbar.

    Wenn du einen Text in Englisch verfassen sollst, überlegst du dir doch nicht die Strukturierung des Textes in deinem Kopf auf englisch, bloß weil das mal die "Ziel-Sprache" ist. Du denkst auf deutsch und übersetzt es ins Englische, wenn es notwendig ist.
     
  5. below

    below Kalterer Böhmer

    Dabei seit:
    08.10.06
    Beiträge:
    2.865
    Wenn ich mich aus dem Fenster lehnen darf:

    Die richtige Antwort ist: "Es kommt darauf an". Wenn man Byte Order swapping braucht, dann ist immer irgendwo ein Bottleneck. Komplexe Strukturen kann man nur mit einem bestimmten Aufwand drehen.

    Dann ist also die Frage: Wann brauche ich die Performance? Bei mir müssen die Daten häufig im Bedarfsfall im Ausgabeformat fix und fertig vorliegen (z.B. DMA), also wandele ich sie direkt wenn ich sie bekomme.
    Bei den meinsten GUI Applikationen würde ich das aber erst direkt vor der Ausgabe in Datei, bzw. bem Einlesen machen.

    Alex
     
  6. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Du lehnst dich überhaupt nicht aus dem Fenster. Wenn du sie in den DMA-Bereich legst, "verlassen Sie dein Programm" so als ob du sie auf Platte schreiben würdest. Und wie hier vorgeschlagen wandelt man sie dann um.

    Wenn du allerdings selbst noch auf diesen Daten arbeiten möchtest, wirst du das sicher nicht in nicht nativer Bytefolge machen, auch dann nicht, wenn die Umwandlung komplex ist.

    Bliebe allenfalls noch der Fall, dass du die Daten "umgekehrt" herein liest und ebenso wieder rausschicken musst. Hier hast du offenkundig überhaupt kein Problem mit Endianess.
     
  7. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.245
    Ich nehme stark an, daß Du Dich hierbei auf Treiber-Entwicklung oder andere Low-Level Aspekte beziehst bei denen es notwendig ist auf irgend welche Hardware-Register o.ä. zuzugreifen. Leider muß man sich dabei mit viel Hardware auseinandersetzen, die nun einmal Daten im Little Endian Format erwartet. Das ist auch eine Folge der Intel Dominanz. Intel Hardware ist schon immer im Little Endian Format gewesen.

    Immer dann wenn Daten aus dem Programm irgend wo hinaus transferiert werden, muß man sich mit der Thema Serialisierung auseinandersetzen, es ist ja nicht nur die Endianness Problematik sondern auch Padding Bytes sind da ein Thema. Wenn man richtig serialisiert, dann umgeht man all diese Probleme.
     
  8. below

    below Kalterer Böhmer

    Dabei seit:
    08.10.06
    Beiträge:
    2.865
    Richtig, ich beziehe mich hier auf Treiber etc. Zu Little Endian: Nicht ausschliesslich, es gibt Sachen, die gibt es gar nicht,zum Beispiel USB Geräte bei denen der Header (natürlich) little Endian, die Payload aber Big Endian sein muss.

    Beziehst Du Dich da jetzt auch auf meinen LowLevel Kram?

    Alex
     
  9. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.245
    Nur bedingt, denn es kann aus Geschwindigkeitsgründen durchaus angebracht sein, von dieser Regel abzuweichen, nur würde ich das nicht ohne triftigen Grund tun. Treiberentwicklung ist so ein Problembereich bei normalen Anwendungen sehe ich da aber eher selten Bedarf.
     
  10. Amin Negm-Awad

    Amin Negm-Awad Süsser Pfaffenapfel

    Dabei seit:
    01.03.07
    Beiträge:
    665
    Na, bedenke dass man zwar Serialisierung meist im Kontext mit Streams verwendet. Aber das ist nicht zwingend. Serialisierung bedeutet (im Wortsinne wie im technischen Sinne) lediglich, dass du einen Graphen in serielle, also abfolgende Anordnung bringst. Dabei spielt es keine Rolle, ob das eine Datei ist oder ein DMA-Bereich. Was du da machst ist auch Serialisierung.

    Ganz wichtig ist dies ja auch im Zusammenhang mit Versand von Daten im Netzwerk.
     

Diese Seite empfehlen