Endian



  • Hallo Liebe Experten,

    ich bemühe mich grade portablen Code für OSX/Win32 zu schreiben und sehe mich
    mit dem Little-Big-Endian Problem konfrontiert.
    Ich brauchen keinen konkreten Code sondern möchte euch fragen welches ihr für
    die sinnvollste und effektifste (evl. mit Stylebonus 🙂 Methode haltet eine
    BigEndian Datei auf einem LittleEndian System zu verarbeiten.

    Der Code ist für Windows bereits implementiert und benutzt massig struct's.

    Was ist am besten?

    - Jedes struct, bekommt eine Memberfunktion 'swapBytes' die
    beim einlesen des File via #ifdef bigEdian aufgerufen wird.

    - Bei #ifdef bigEndian das File komplett in den Speicher lesen, die Daten
    zu BigEndian konvertieren, als temp Kopie speichern und dann normal weiter
    auf dem temp File. (so könnte ich am meisten Code weiter benutzen)

    - Die Datei gleich rückwärts lesen, geht das?

    Gruß
    Marcel



  • mit dem endian haben nur die marken(sprich variablen- und funktions-positionen) und nicht die komplete exe-file. somit ist

    Binarys schrieb:

    - Die Datei gleich rückwärts lesen, geht das?

    nicht möglich.
    willst du überhaupt exe-files oder code-files endian umwandeln? beim code müsste das (glaube ich: in c/c++) beim linken passieren. aber ein normaler compiler bring die funktion schon mit sich. gcc > --big-endian oder --little-endian als parameter übergeben. und exe-files kenne ich keine möglichkeit und ich vermutte auch mal das sowas nicht geht.



  • Im Quellcode selbst ist das transparent und daher sind keine Änderungen notwendig, außer man macht irgendwelche spezielle Sachen auf Byte-Arrays.

    Nur z.b. solche Sachen müssen gesondert behandelt werden:

    int sei 32bit groß

    little endian variante:

    int i = 12345678;
    char * p = (char *)&i;
    char lsb = p[0];

    big endian:

    int i = 12345678;
    char * p = (char *)&i;
    char lsb = p[3];



  • Hi, eigentlich will ich nur eine Binär-Datei einlesen.
    (und dabei so wenig code wie möglich anpassen müssen)
    Leider sind meine bisherigen Versuche nicht von Erfolg
    gekrönt.

    [cpp]
    int length;
    char * buffer;
    
    //die Litte-Endian Binardatei öffnen und lesen
    ifstream ifs (filename, ios::binary | ios::in);
    ifs.seekg (0, ios::end);
    length = ifs.tellg();
    ifs.seekg (0, ios::beg);
    buffer = new char [length];
    ifs.read (buffer,length);
    ifs.close();
    
    // unter OSX den buffer von Litte-Endian nach Big-Endian swapen
    register int i = 0;
    register int j = length;
    while (i<j)
    {
       swap(buffer[i], buffer[j]);
       i++, j--;
    }
    // ... weiter wie unter Win
    [/cpp]
    

    Also, zu mindest in meiner Fantasie, sollte das den ganzen datei
    inhalt einmal umdrehen. Klappt aber nicht 😞



  • du kannst nicht einfach die datei umkehren. das endian wirkt sich nicht auf die komplete datei aus, sondern unr auf positionen, sprich marken und variablen.
    ein kleines assembler-beispiel:

    jmp addresse
    variable dd 12
    addresse:
    add ax, variable
    

    sprunglänge jmp -> addresse = 4byte.
    variable = 0C hex.
    dieser code wird zu EB 04 00 0C 00 00 00 83 C0 02 assembliert. dabei ist kursiv die addresse und fett die variable darstellt. diese ist nun in little-endian und deswegen ist 04 0C vorne. willst du es in big-endian müsste die bin so aussehen: EB 00 04 00 00 00 OC 83 C0 02 aussehen.
    diese marken (addressen) sind in c++ z.b. jedes if .. else und so ziemlich die komplete syntax. (auch goto :))

    wenn du jetzt eine binary hast bei der du nicht weist wo sich die maken befinden, die du rückwärts speichern sollst, dann kannst du deine datei auch nicht konvertieren.



  • Super, vielen dank!

    Das erklärt mein Problem und die Lösung ist dann auch klar
    (mein erster Ansatz weiter oben).

    Danke! 👍
    Lg



  • Ob man swapen muß, hängt ganz vom Dateiformat ab.
    Swapen muß man nur Werte, die aus mehren Bytes bestehen.
    Gewöhnliche Byte-streams werden hingägen überall gleichbehandelt.
    Wenn es sich z.b um ein int-stream handelt, muß man alle ints swappen.
    Big-Endian bedeutet sicher _nicht_, daß der byte-stream komplett umgedreht im File steht.

    MfG, Michael

    PS. Ich habe damit Erfahrungen (z.b. DICOM-Format, daß sowohl Little-Endian, als auch Big-Endian codiert sein kann)



  • @Binarys

    MichiK schrieb:

    Swapen muß man nur Werte, die aus mehren Bytes bestehen.
    Gewöhnliche Byte-streams werden hingägen überall gleichbehandelt.

    ja genau. ein string bleibt so wie er ist. also "string" wird nicht zu "gnirts" ⚠

    @MichiK
    was ist DICOM??? 😕



  • DICOM ist ein Format für die Übertragung von medizinischen Daten (Digital Imaging and Communications in Medecine), s.a http://de.wikipedia.org/wiki/DICOM
    Auch dort muß man je nach Plattform die Daten entsprechend der Endian-Order behandeln (aber dies ist bei diesem Standard genau spezifiziert).

    Ich weiß das, weil ich selber einen DICOM-Viewer und WebClient geschrieben habe (welcher Daten von einem DICOM-Server abruft).

    Und MichiK, was hast du mit DICOM zu schaffen?


Anmelden zum Antworten