htonl, ntohl für ganze Strukturen



  • Hallo zusammen,
    gibt es eine Funktion, Makros oder ein Trick mit dem ich ganze Strukturen oder Objekte in die NetByteOrder versetzten oder wieder zurücksetzen kann?

    Vielen Dank vorab...

    Gruss Christian

    P.S. und frohes neues Jahr posthum :xmas1:



  • dazu musst du uns aber sagen, wieviele bytes vertasucht werden sollen

    z.b.

    htons:
    [1][2] -> [2][1]

    htonl:
    [1][2][3][4] -> [4][3][2][1]

    willst du die ganze struktur umkehren oder nur 2-byte-päckchen?
    ein kleiner unsiversaler ungetesteter tauscher für beliebige größen

    void hton_struct(void *struct, unsigned size, unsigned swapsize)
    {
        char *from = (char *)struct;
        char *to = (char *)struct + swapsize - 1;
        char *end = (char *)struct + size - 1;
    
        while (to <= end)
        {
            for (char *t1 = from, *t2 = to; t1 <= t2; ++t1, --t2)
            {
                char temp = *t1;
                *t1 = *t2;
                *t2 = temp;
            }
            from += swapsize;
            to += swapsize;
            if (to > end && to - swapsize <= end)
                to = end;
            if (from > to)
                from -= swapsize;
        }
    }
    struct test
    {
        int a, b, c, d;
    };
    int main()
    {
        test t;
        t.a = 42;
        t.b = 1000;
        t.c = 822446
        t.d = 27;
        nton_struct(&t, sizeof(t), 4); // tauscht [4][3][2][1][8][7][6][5][12][11]...
    }
    


  • columbus schrieb:

    Hallo zusammen,
    gibt es eine Funktion, Makros oder ein Trick mit dem ich ganze Strukturen oder Objekte in die NetByteOrder versetzten oder wieder zurücksetzen kann?

    leider nicht. ein compiler darf dir z.b. lücken in die structs basteln, weil er gern gewisse members an 2-byte, 4-byte-grenzen usw. ausrichtet. wenn du eine struct als char-array interpretierst und einfach die bytes umdrehst, wird manchmal mist rauskommen.
    🙂



  • gibt es eine Funktion, Makros oder ein Trick mit dem ich ganze Strukturen oder Objekte in die NetByteOrder versetzten oder wieder zurücksetzen kann?

    Muß das mit ANSI-Mitteln sein, oder darf man direkt an das Betriebsystem übergeben?



  • ~fricky schrieb:

    columbus schrieb:

    Hallo zusammen,
    gibt es eine Funktion, Makros oder ein Trick mit dem ich ganze Strukturen oder Objekte in die NetByteOrder versetzten oder wieder zurücksetzen kann?

    leider nicht. ein compiler darf dir z.b. lücken in die structs basteln, weil er gern gewisse members an 2-byte, 4-byte-grenzen usw. ausrichtet. wenn du eine struct als char-array interpretierst und einfach die bytes umdrehst, wird manchmal mist rauskommen.
    🙂

    Selbst ohne padding würde das schon nicht gehen:

    struct foo {
        int32_t a;
        int16_t b;
        int16_t b;
    }
    

    Das kann man schon nicht allgemeingültig um-endianessen ohne die Größen der einzelnen Member zu kennen.



  • columbus schrieb:

    Hallo zusammen,
    gibt es eine Funktion, Makros oder ein Trick mit dem ich ganze Strukturen oder Objekte in die NetByteOrder versetzten oder wieder zurücksetzen kann?

    Vielen Dank vorab...

    Gruss Christian

    P.S. und frohes neues Jahr posthum :xmas1:

    Warum sollte man das tun wollen?



  • Tim schrieb:

    Selbst ohne padding würde das schon nicht gehen:

    und auch nicht, wenn irgendwas drin ist, das nicht vertauscht werden darf, wie strings und char-arrays z.b.
    🙂



  • ~fricky schrieb:

    Tim schrieb:

    Selbst ohne padding würde das schon nicht gehen:

    und auch nicht, wenn irgendwas drin ist, das nicht vertauscht werden darf, wie strings und char-arrays z.b.
    🙂

    Ja, das denke ich auch. Ich habe zwar mit alignment eingeschaltet

    #pragma pack(1)
    

    also padding habe ich keines. Aber ich habe eben auch noch Unterstrukturen in meiner Struktur. Also ich muss wohl oder übel jedes Member einzeln in Network-Byte-Order umwandeln.

    Aber trotzdem vielen Dank für die vielen Bastelanregungen 😉

    Gruss Christian


Anmelden zum Antworten