unsigned char in unsigned long und zurück
-
Hallo!
Mit folgendem Code kann ich einen u-long in einen u-char und zurück konvertieren. (Nicht die "Zahlenwerte" wie atol, ltoa).
inline unsigned long __fastcall UCharToULong (unsigned char pBuf[4]) { return (pBuf[0] << 24 | pBuf[1] << 16 | pBuf[2] << 8 | pBuf[3]); } inline char * __fastcall ULongToUChar (unsigned long lVal, unsigned char pBuf[4]) { pBuf[0] = (unsigned char) ( lVal >> 24 ) & 0xff; pBuf[1] = (unsigned char) ( lVal >> 16 ) & 0xff; pBuf[2] = (unsigned char) ( lVal >> 8 ) & 0xff; pBuf[3] = (unsigned char) lVal & 0xff; return pBuf; }
Der Code funktioniert wunderbar. Doch verstehe ich "ihn" nicht wirklich. Könnte mir wohl jemand erklären warum genau diese Bitoperationen nötig sind und/oder woher man so etwas weiß?
Kann der Code unter Umständen Probleme machen (Ich meine keine Platformschwierigkeiten wo ein long z.b. != 4 Bytes und/oder ein char != 1 Byte ist)?Gruß Ulrich
-
Beim ersten werden die chars erst implizit nach unsigned long konvertiert dann geshiftet, so dass die bits an der richtigen stelle stehen und danach mittels bitweisem oder zu einem einziegen unsigned long.
Am anfang siet das vielleicht so aus:pBuf[0]: 00101110 pBuf[1] 11010001 pBuf[2] 10010110 pBuf[3] 00100101
Wenn die jetzt implizit nach unsigned long gecasted werden, wird einfach vorne mit Nullen aufgefüllt, sie sehen jetzt so aus:
pBuf[0] als unsigned long: 00000000000000000000000000101110 pBuf[1] als unsigned long 00000000000000000000000011010001 pBuf[2] als unsigned long 00000000000000000000000010010110 pBuf[3] als unsigned long 00000000000000000000000000100101
Danach werden die unsigned longs unterschiedlich weit geshiftet:
pBuf[0] als unsigned long << 24: 10111000000000000000000000000000 pBuf[1] als unsigned long << 16 00000000110100010000000000000000 pBuf[2] als unsigned long << 8 00000000000000001001011000000000 pBuf[3] als unsigned long 00000000000000000000000000100101
Jetzt mittels bitweisem oder verknüpfen: die bits von zwei unsigned longs werden verglichen, wenn von 2 "parallelen" bits eins gesetzt ist, ist es auch im Ergebnis gesetzt:
Ergebnis: 10111000110100011001011000100101
(kann sein, dass ich mit den bits jetzt was durcheinander gehauen hab...
Zurück gehts genau andersrum...
-
Ulli schrieb:
Mit folgendem Code kann ich einen u-long in einen u-char und zurück konvertieren.
Nicht ganz. Erstens hast du hier ein unsigned char Array, das ist schon ein Unterschied. Und zweitens wird hier nicht konvertiert, sondern vielmehr die Reihenfolge umgedreht.
Ulli schrieb:
Kann der Code unter Umständen Probleme machen
Ausser Plattform spezifischen Sachen eigentlich nicht.
Du solltest aber darauf achten, ein 'unsigned char*' in ULongToUChar zurückzugeben, wenn du schon ein solches Array als Parameter übergibst.