2016-04-25 10 views
-2

Ich schreibe ein Programm, das MIDI-Dateien erstellt, und ich versuche, die Midi-Nachrichten in einer Datei zu schreiben.Bytes in Dateien richtig schreiben in C/C++ [Endianess]

Ich getestet zuerst den ganzen Weg, um Datei von Null mit der Funktion fputc() und die Eingabe Byte pro Byte die ganze Datei zu erstellen, und es ging gut.

Das Problem kam, als ich mehr als ein Byte gleichzeitig zu schreiben versucht (beispielsweise ein oder ein short intint in die Datei zu schreiben), da die Funktion fwrite() rückwärts das Bytes gesetzt.

Zum Beispiel:

FILE* midiFile; 

midiFile = fopen("test.mid", "wb"); 

short msg = 0x0006; 

fwrite(msg, sizeof(msg), 1, midiFile); 

fclose(midifile); 

Die Ausgabe int die Datei geschrieben seine 0x06 die 0x00 und nicht die erwarteten: 0x00,0x06.

Ich lese darüber, und finde, dass es durch die endianness verursacht wird; mein Intel-Prozessor verwendet Little Endian so schreibt Variablen größer als 1 Byte rückwärts (im Vergleich zu einem Big Endian Maschine).

Ich muss noch das korrigieren und die Bytes so schreiben, wie ich mein Programm entwickeln möchte.

Mein Compiler nicht identifiziert Funktionen wie htonl() oder ähnlich (ich weiß nicht, warum), aber ich frage einen Weg, es zu tun, oder wie short ‚s und int‘ s auf char-Arrays schreiben (vor allem short 's).

+0

Sofern Sie einen Link zu der Beschreibung der "C/C++" Sprachen zur Verfügung stellen können, bitte ein von C wählen ** oder ** C++. Sie sind verschiedene Sprachen! Und es gibt mehr potenzielle Probleme mit Ihrem Code. Um interne Daten zu übertragen/speichern, verwenden Sie das richtige _marshalling_ und verwenden Sie _fixed size_. – Olaf

+1

@Olaf, in diesem speziellen Fall wäre die Antwort die gleiche, also c- und C++ - Tags sind angemessen. Andernfalls würden Sie sagen, dass für die Frage nicht mehr als ein Tag erlaubt ist. – SergeyA

+0

@SergeyA: Nicht einverstanden. Ordentliches Marshalling kann mit einem OOP-Ansatz, der in C und C++ sehr unterschiedlich implementiert werden müsste, stark vereinfacht werden. – Olaf

Antwort

0

Entweder schreibt die Bytes, die Sie wollen, um, einen nach dem anderen ...

oder das Bytes tauschen, bevor Sie sie schreiben.

uint8_t msbyte = msg >> 8; 
uint8_t lsbyte = msg & 0xFF; 

uint8_t buffer[2]; 
// Big Endian 
buffer[0] = msbyte; 
buffer[1] = lsbyte; 

/* Little endian 
buffer[0] = lsbyte; 
buffer[1] = msbyte; 
*/ 
fwrite(&buffer[0], 1, sizeof(buffer), midiFile); 

Swapping Bytes:

uint16_t swap_bytes(const uint16_t value) 
{ 
    uint16_t result; 
    result = value >> 8; 
    result += (value & 0xFF) << 8; 
    return result; 
}