2016-12-21 2 views
0

Ich benutze eine Third-Party-Bibliothek (mavlink), die eine Anzahl von Strukturen definiert, die alle mit __attribute__((packed)) markiert sind, so dass sie effizient über eine serielle Verbindung übertragen werden können (es ist in C geschrieben und ich bin Verwendung in einer C++ - Anwendung). Wenn ich sie erhalte und rekonstruiere, möchte ich ihnen ein Zeitstempelfeld hinzufügen. Ich denke, der einfachste Weg ist, eine neue Struktur zu erstellen, die die vorhandene Struktur erbt. das heißt in der mavlink Bibliothek wird diese Struktur definiert:Erben einer gepackten C-Struktur

MAVPACKED(
typedef struct __mavlink_heartbeat_t { 
uint32_t custom_mode; 
uint8_t type; 
uint8_t autopilot; 
uint8_t base_mode; 
uint8_t system_status; 
uint8_t mavlink_version; 
}) mavlink_heartbeat_t; 

wo MAVPACKED ein Makro, das __attribute__((packed)) gilt. sizeof(mavlink_heartbeat_t) kehrt 9. Wenn ich

struct new_heartbeat_t : mavlink_heartbeat_t 
    { 
     uint64_t timestamp; 
    }; 

sizeof(new_heartbeat_t) Renditen 24 definieren, so sieht es aus wie 7 Füllbytes hinzugefügt werden (I bis Ende mavlink_heartbeat_t annehmen würde, so dass Zeitstempel beginnen bei Byte 16.)

Existieren Irgendwelche Fehler oder Dinge, die du beachten musst, oder gibt es einen besseren Weg?

+0

Verkapselung auf lange Sicht besser verwaltbar sein könnte. –

+0

Sie können versuchen, das Attribut __ ((__ gepackt)) auf Ihre Struktur anzuwenden und die Größe zu überprüfen. – manu

+0

@RichardHodges wie meinst du das? Meinst du statt "mavlink_heartbeat_t" zu vererben, um es zu einem privaten Mitglied der neuen Struktur zu machen und dann jedem Mitglied von 'mavlink_heartbeat_t' Zugriffsrechte zu geben? –

Antwort

0

Vererbung ist eine ist eine Art Beziehung.

Ist die lokale Darstellung eines Herzschlags wirklich eine Art Draht Nachricht? Ich bezweifle das.

Aber es könnte vernünftigerweise eins enthalten.

Ich würde kapseln es so etwas wie dieses:

#include <cstdint> 
#include <cstddef> 


typedef struct __attribute__((packed)) __mavlink_heartbeat_t { 
uint32_t custom_mode; 
uint8_t type; 
uint8_t autopilot; 
uint8_t base_mode; 
uint8_t system_status; 
uint8_t mavlink_version; 
} mavlink_heartbeat_t; 


extern std::uint64_t now(); 
void sync_fetch_data(mavlink_heartbeat_t&); 
void foo(uint8_t); 

struct local_heartbeat 
{ 

    mavlink_heartbeat_t const& get_io_buffer() const { 
    return io_buffer_; 
    } 

    mavlink_heartbeat_t& prepare_receive() { 
    request_timestamp_ = now(); 
    return io_buffer_; 
    } 

    void complete_receive() { 
    response_timestamp_ = now(); 
    } 


    std::uint64_t get_response_timestamp() const { 
    return response_timestamp_; 
    } 

private: 
    // stuff in here might have suspect alignment 
    mavlink_heartbeat_t io_buffer_; 

    // but these will be aligned for optimal performance 
    std::uint64_t request_timestamp_; 
    std::uint64_t response_timestamp_; 
}; 



int main() 
{ 

    // create my local representation 
    local_heartbeat hb; 

    // prepare it to receive data 
    auto& buffer = hb.prepare_receive(); 

    // somehow populate the buffer 
    sync_fetch_data(buffer); // could be async, etc 

    // notify the object that reception is complete 
    hb.complete_receive(); 

    // now use the local representation 
    foo(hb.get_io_buffer().system_status); 

}