struct-Objekt auf Bytedaten aus serieller Schnittstelle konstruieren



  • Hiho,

    ich habe folgenden Sachverhalt. Ich bekomme Daten von einem Lasersensor über eine serielle Schnittstelle rein. Zu dem Sensor gibt es eine Doku wie ein Telegram aufgebaut ist. Ich könnte jetzt natürlich anfangen durch Picken der Adressen und casten die einzelnen Daten da rauszuholen. Das finde ich aber sehr umständlich. Ich habe das daher so gelöst:

    #pragma pack(push, 1) // exact fit - no padding
    
    struct TgHeader
    {
    	//
    	unsigned int head;
    	//
    	unsigned short block_number;
    	//
    	unsigned short size;
    };
    
    #pragma pack(pop) //back to whatever the previous packing mode was
    
    ...
    
    auto& header = *new(&m_buffer[0]) TgHeader;
    

    Ich habe ein Struktur mit dem Aufbau definiert, durch pragma pack das Padding auf 1 gesetzt und erzeuge dann mit placement new auf dem vorhandenen Speicher mein Objekt. Dieses muss man dann auch nicht mit delete freigeben, da es ja auf geborgtem Speicher sitzt.

    Frage Nummer eins: Ist das ISO-Konform, oder könnte es sein, dass beim Konstruieren des Objektes der Speicher geändert wird (meine Struct hat keinen von mir definierten Konstruktor)?

    Frage 2: haltet ihr das für ein sinnvolle Lösung oder gibt es bessere Ideen? Ich fand es so zumindest besser, als jeden einzelnen Typ dann mit reinterpret_cast zu erhalten. Das Objekt wird auch nur intern in meiner Parserklasse verwendet und genutzt und nie nach außen gegeben.

    VG

    Pellaeon


  • Mod

    Das ist in Ordnung, sofern du dich auf die Größe von unsigned int verlässt. Wenn du es ganz penibel haben möchtest, müsstest du dort Typen mit fester Größe nehmen. Und ultra-penibel musst du noch die Endianess beachten.

    Das mit dem placement-new kommt mir unnötig umständlich vor. Die Lösung mit dem Cast ist besser.



  • Endianess tu ich nachträglich noch beachten, weil die Daten gemischt kommen, Header Big Endian, Nutzdaten little endian.

    Ok also lieber mit reinterpret_cast:

    auto& header = *reinterpret_cast<TgHeader*>(&m_buffer[0]);
    
    header.block_number = utility::nw::networkToHost(header.block_number);
    header.size			= utility::nw::networkToHost(header.size);
    

Anmelden zum Antworten