it-swarm.com.de

Konvertieren Sie Bytes in C in Int/uint

Ich habe ein vorzeichenloses Zeichenarray [248]; mit Bytes gefüllt. Wie 2F AF FF 00 EB AB CD EF ......... Dieses Array ist mein Byte-Stream, in dem ich meine Daten aus dem UART (RS232) als Puffer ablege.

Jetzt möchte ich die Bytes zurück in meine uint16's und int32's konvertieren.

In C # habe ich dazu die BitConverter-Klasse verwendet. z.B:

byte[] Array = { 0A, AB, CD, 25 };
int myint1 = BitConverter.ToInt32(bytes, 0);
int myint2 = BitConverter.ToInt32(bytes, 4);
int myint3 = BitConverter.ToInt32(bytes, 8);
int myint4 = BitConverter.ToInt32(bytes, 12);
//...
enter code here
Console.WriteLine("int: {0}", myint1); //output Data...

Gibt es eine ähnliche Funktion in C? (Nein. net, ich verwende den KEIL-Compiler, da auf einem Mikrocontroller Code ausgeführt wird) 

Mit freundlichen Grüßen Sam

10
Sam

Ja da ist. Angenommen, Ihre Bytes befinden sich in:

uint8_t bytes[N] = { /* whatever */ };

Wir wissen, dass eine 16-Bit-Ganzzahl nur aus zwei 8-Bit-Ganzzahlen besteht, d. H. Eine mit einem Vielfachen von 256 oder alternativ um 8 verschoben ist:

uint16_t sixteen[N/2];

for (i = 0; i < N; i += 2)
    sixteen[i/2] = bytes[i] | (uint16_t)bytes[i+1] << 8;
             // assuming you have read your bytes little-endian

Ähnlich für 32 Bits:

uint32_t thirty_two[N/4];

for (i = 0; i < N; i += 4)
    thirty_two[i/4] = bytes[i] | (uint32_t)bytes[i+1] << 8
        | (uint32_t)bytes[i+2] << 16 | (uint32_t)bytes[i+3] << 24;
             // same assumption

Wenn die Bytes Big-Endian sind, wird die Reihenfolge natürlich umgekehrt:

bytes[i+1] | (uint16_t)bytes[i] << 8

und

bytes[i+3] | (uint32_t)bytes[i+2] << 8
    | (uint32_t)bytes[i+1] << 16 | (uint32_t)bytes[i] << 24

Beachten Sie, dass es einen Unterschied zwischen dem Endian-Wert der gespeicherten Ganzzahl und dem Endian-Wert der laufenden Architektur gibt. Der Endian-Wert, auf den in dieser Antwort Bezug genommen wird, ist von der gespeicherten ganzen Zahl, d. H. Dem Inhalt von bytes. Die Lösungen sind unabhängig von der Endian-Ness der laufenden Architektur, da Endian-Ness beim Verschieben berücksichtigt wird .

10
Shahbaz

In C gibt es keine Standardfunktion für Sie. Sie müssen die Bytes wieder in Ihre 16- und 32-Bit-Ganzzahlen einfügen. Sei vorsichtig mit der Endianness!

Hier ist ein einfaches Beispiel für Little Endian:

extern uint8_t *bytes;
uint32_t myInt1 = bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24);

Für ein Big-Endian-System ist es genau die umgekehrte Reihenfolge:

uint32_t myInt1 = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];

Möglicherweise können Sie mit:

uint32_t myInt1 = *(uint32_t *)bytes;

Wenn Sie bei Ausrichtungsproblemen vorsichtig sind.

17
Carl Norum
            char letter = 'A';
            size_t filter = letter;
            filter = (filter <<  8 | filter);
            filter = (filter << 16 | filter);
            filter = (filter << 32 | filter);
            printf("filter: %#I64x \n", filter); 

ergebnis: "Filter: 0x4141414141414141"

0
Andre

Können Sie im Falle von Little-Endian nicht einfach memcpy verwenden?

memcpy((char*)&myint1, aesData.inputData[startindex], length);
0
Sven Depoorter