2011-01-08 7 views
1

gehe ich davon haben die struct Foobesseren Weg, um Strukturgröße (#pragma pack VS definierten Größe) Bezug zu nehmen

struct Foo{ 
    int a; 
    short b; 
    char c; 
}; 

und ich habe diese Struktur in N/w-Puffer zu schreiben. Ich muss die Größe dieser Struktur wissen. In meiner Umgebung gibt sizeof (Foo) 8 zurück, das ist in Ordnung, ich verstehe.

Dies sind zwei Wege, um die genaue Größe zu beziehen, die ich

1. #define SIZEOF_FOO 7, in den Puffer schreiben wollen Und das sizeof(Foo) statt
2. Durch die Verwendung von #pragma pack verwenden, so kann ich sizeof(Foo) verwenden denen zurück 7

Welcher ist der bessere Weg, oder gibt es einen anderen Weg, dies zu tun?

+0

Was ist deine Absicht? Zu jeder Zeit die Größe von Foo zu kennen oder die Größe von Foo auf einen bestimmten Wert zu setzen? In der Tat, sizeof (Foo) gibt die tatsächliche Größe von Foo zurück, und Ihre Erwartung, dass es 7 ist, ist falsch. Sie müssen die tatsächliche Anzahl der Bytes in den Puffer schreiben, nicht die Nummer, die die Struktur haben soll. Wenn Sie Konstanten verwenden, wird auch nicht garantiert, dass sowohl der Absender als auch der Empfänger die gleiche Größe wie Foo haben. – mbaitoff

+0

Nun, der Punkt ist der Empfänger ist in dem anderen System, und es erwarten die ersten 4 Bytes "a" -Wert, und so weiter, nächste 2 Bytes ist "b", nächste 1 Byte ist c. Es ist das Problem, wenn es Padding 0 nach "c" bezüglich der Schreibgröße 8 (von sizeof) anstelle von 7 hinzufügt. Und es beschädigt den Puffer-Stream. – Summerpinn

Antwort

2

Wenn Sie eine solche Struktur in ein Netzwerk schreiben müssen, verwenden Sie bitte ein Protokollframework oder marshalieren Sie die Daten explizit mit einem Protokoll, das Sie unabhängig vom Strukturlayout definieren.

Abhängig von der binären Layout-Details einer Struktur wird wahrscheinlich verursachen Schmerzen auf der Straße.

Ich habe gute Dinge über Google Protocol Buffers und Boost serialization gehört, aber ich habe auch nicht verwendet.

Ich habe ein in einem Dokument definiertes Protokoll behandelt und die Daten gemäß diesem Protokoll mit benutzerdefinierten Marshalling-Routinen ausgegeben oder eine IDL-Beschreibung verwendet (ähnlich wie eine annotierte C-Struktur, die einen Code steuert) Generator, der die Serialisierungs-/Deserialisierungsroutinen verkettet).

Auf diese Weise steuern Sie (oder das Protokoll-Framework) die Verwendung von Auffüllung, unabhängig davon, was der Compiler für die Struktur tut. Beachten Sie, dass Sie ein Protokollframework verwenden, das Sie normalerweise an beiden Enden verwenden müssen (was ein Problem sein kann, wenn der andere Knoten nicht von Ihnen kontrolliert wird oder ein eingebettetes Gerät, das das Framework beispielsweise nicht unterstützt).

0

Die Direktive #pragma pack ändert die aktuelle Alignment-Regel für Elemente von Strukturen, die der Direktive folgen. Daher beeinflusst es die Größe der definierten Strukturen nach das Pragma!

Sie brauchen dies wahrscheinlich nicht. Verwenden Sie einfach sizeof(Foo), wo immer Sie die Größe Ihrer Struktur wissen möchten. Und schreibe keine Pragmas, wie sie in einigen speziellen Fällen verwendet werden!

können Sie diese Links sehen in Details über Pragmas wissen:

GCC - Structure-Packing Pragmas
MSVC++ - Pack
pragma pack

0

Diese Frage schwer fehlgeleitet ist. Die Größe Foo ist immer was auch immer sizeof(Foo) zurückgibt. Gehen Sie nicht davon aus, verwenden Sie kein Wunschdenken, verwenden Sie sizeof.

In der Tat würde ich erwarten, dass sizeof(Foo) 12 sein, alles auf einer 4-Byte-Grenze ausrichten.

Wie auch immer, die gute Nachricht ist, dass sizeof zur Kompilierzeit aufgelöst wird, und hat absolut keinen Einfluss auf die Leistung. Also, es gibt keinen Grund, es nicht zu benutzen.

#define SIZEOF_FOO (sizeof(Foo)) 
+0

Nur neugierig: Warum erwarten Sie, dass es 9 ist? – Mehrdad

+0

Ich erwarte, dass 'sizeof (Foo)' 8 ist, da 'short' und 'char' innerhalb von 4 Byte Grenze passen würden! – Nawaz

+0

Ich hatte zunächst 12, aber getrimmt es auf 9, weil ich dumm war. Ich habe es auf 12 neu bearbeitet. –

0

Ich würde empfehlen, Struktur durch sequenzielles Schreiben seiner Mitglieder zu schreiben. Z.B. Sie können Boost-Serialisierung verwenden.

Dadurch wird die Darstellung der Struktur im Anwendungsspeicher von dem für die Übertragung verwendeten Format getrennt.

0

#define SIZEOF_FOO 7 ohne Verwendung von #pragma pack sollte überhaupt nicht verwendet werden. Wenn Sie send (oder eine gleichwertige) Funktion aufrufen, die eine Variable Ihres Strukturtyps übergibt und die Datengröße als 7 übergibt, sendet die Sendefunktion nur die ersten 7 Datenbytes, und wenn Sie diese Daten an der Anderes Ende, Sie werden definitiv eine Menge Dinge in Ihrem Code durcheinander bringen.

Die Verwendung von #pragma pack Direktiven wird die Ausrichtung von Mitglied Ihrer Struktur ändern und Sie werden sicherlich ein paar Bytes Daten über die Netzwerkübertragung speichern, aber wenn Sie in Bezug auf Optimierung/Leistung denken, sind diese paar Bytes vernachlässigbar. Obwohl die meisten Anwendungen (die ich gesehen habe) #pragma pack zum Packen von Strukturelementen verwenden, hängt das jedoch völlig von Ihrer Anforderung ab.

Ein großes Problem bei der Verwendung einer #define SIZEOF_FOO 7 ist, dass, wenn Sie Ihren Code auf eine andere Plattform/Architektur portieren, die tatsächliche Größe Ihrer Struktur nicht identisch (7 Bytes) und dann müssen Sie entweder eine Plattform verwenden abhängiges Makro oder eine andere Alternative.

Kurz gesagt, sollten Sie immer sizeof statt #define SIZEOF_FOO verwenden.

Verwandte Themen