2013-02-22 7 views
5

Für einen angegebenen Kommunikationsstandard RTCM SC104 3.1 muss ich Daten über Bytes als ein Paar von 12-Bit-Datensegmenten aufteilen. Also muss ich für eine gegebene Nachricht die Nummer des Nachrichtentyps auf das erste Byte und die Hälfte des zweiten Bytes setzen. Dann muss ich eine ID-Ganzzahl auf der Hälfte des zweiten Bytes beginnen und mit dem dritten Byte fortfahren. Diese Art von Muster wird bis zum Ende der Nachricht fortgesetzt, wobei andere Ganzzahlen in 20-Bit-, 5-Bit- und anderen Größen heruntergeschnitten werden, wobei im wesentlichen die 0-Werte ausgeschnitten werden, die normalerweise das MSB-Ende der ganzzahligen Werte ausfüllen würden.Wie greift man auf ein einzelnes Byte einer ganzen Zahl zu?

Ich habe keine klare Definition gesehen, aber ich nehme an, dass es in der Netzwerkbyte-Reihenfolge ausgehen muss, also würde ich vor dem Kopieren von Bits meine ganzen Zahlen im Speicher umkehren müssen. Ich bin immer noch ziemlich neu in cpp und frage mich, wie komme ich zu den einzelnen Bytes, die eine ganze Zahl im Speicher bilden? Wenn ich auf die Bytes zugreifen kann, dann könnte ich bitweise verwenden oder die Bits von 2 Bytes auf eins für die Nachricht aufteilen.

Hier ist der Beginn eine Nachricht zu bauen, bevor die Daten hinzufügen:

//build message 1002 gps 00111110 1010 
    char buf1002[BUFFERSIZE]; 
    buf1002[0] = 0x3E; //00111110 
    buf1002[1] = 0xA0; //10100000 
//ref station id 12 bits of 16 
//ex unsigned short m = 1100; 
//m would be byte2 00000100 byte1 01001100 
//buf1002[1] would be 10100100 
//buf1002[2] would be 01001100 
//reverse bit order for network after building? 

Die Referenzstation von einer unsigned short sein wird, so dass eine 2-Byte-Ganzzahl. Wie kann ich ein einzelnes Byte daraus lesen? Beginne ich mit einem Speicherzeiger? Wenn ja, was?

Jede Hilfe würde sehr geschätzt werden.

+0

Lesen Sie die erste Antwort hier http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c –

+4

* "Die Referenzstation wird von einem unsigned short, also einer 2-Byte-Integer. "* Ein Short ist nicht erforderlich, um zwei Bytes zu sein (obwohl dies der bei weitem häufigste Fall ist), es muss * mindestens * 16 Bits sein. Sie könnten 'uint16_t' verwenden, um die Angelegenheit zu erzwingen. – dmckee

Antwort

0

Sie greifen als Bytes punning, zum Beispiel:

const unsigned short s(1); 
const char* const bytes(reinterpret_cast<const char*>(&s)); 

const char NaturalOrder[sizeof(s)] = {bytes[0],bytes[1]}; 
const char EndianFlipped[sizeof(s)] = {bytes[1],bytes[0]}; 

(Aber auch Dmckee Kommentar in Bezug auf die natürliche Größe builtins und prüfen, mit fester Breite Typen sehen).

2

Wenn Sie Ihre ganze Zahl, die wie 00001000 00000000 11000000 00110000 zum Beispiel (ich bin Räume Unterschied machen jedes einzelne Byte), einer in einem int in Beispiel enthalten:

int  a; 
int  single_byte; 

a = the_number; 

Sie eine Funktion tun könnte wie

int  get_byte_in_integer(int byte_number, int integer); 

so dass:

single_byte = get_byte_in_integer(1, a); // That would give you the 11000000 byte 

mit

int get_byte_in_integer(int byte_number, int integer) 
{ 
     return (integer >> (byte_number << 3)) & 0xff); 
} 

Hoffe dies hilft, für den Byte-Teil.

4

können Sie Bit-Felder verwenden, wie dies - einige Einsprüche am Ende:

typedef union packet { 
    struct { 
     unsigned int msgno : 12; // creates a 12 bit wide integral field 
     unsigned int msgtype : 12; 
     unsigned int somefield2 : 3; 
     unsigned int somefield3 : 5; 
    } fields; 

    unsigned char asbytes[4]; 
} packet; 

... 

packet p; 
// fill it, by using the field side of the union 
p.fields.msgno = 16; 
p.fields.msgtype = 12; 
p.fields.somefield2 = 6; 
// and retrieving them as regular bytes 
unsigned char abyte = p.asbytes[0]; 
abyte = p.asbytes[1]; 
// and so on 

Für mich ist der Hauptvorteil ist die Lesbarkeit: alle Operationen wie normale Operationen verhalten auf, wenn auch schmalere Integraltyp-Variablen.Es gibt Einschränkungen (z. B. Portabilität), aber wenn Sie nicht auf mehrere Architekturen oder Compiler oder andere Endianer abzielen, kann dies dazu beitragen, dass Ihr Programm viel einfacher zu lesen ist.

+0

Ich mag deine Idee. Es ist ein ganz anderer Ansatz zum Erstellen der gesamten Nachricht in einem Array, das ich den Socket senden konnte. Es dauerte eine Weile, bis ich herausgefunden hatte, was es gerade tat. –

Verwandte Themen