StructLayoutAttribute.Pack Field

Definition

Steuert die Ausrichtung der Datenfelder einer Klasse oder Struktur im Speicher.Controls the alignment of data fields of a class or structure in memory.

public: int Pack;
public int Pack;
val mutable Pack : int
Public Pack As Integer 

Field Value

Int32

Remarks

Das Feld "Pack" steuert die Ausrichtung der Felder eines Typs im Arbeitsspeicher.The Pack field controls the alignment of a type's fields in memory. Dies wirkt sich auf LayoutKind.Sequential und LayoutKind.Explicitaus.It affects both LayoutKind.Sequential and LayoutKind.Explicit. Standardmäßig ist der Wert 0 (null), der die Standard Komprimierungs Größe für die aktuelle Plattform angibt.By default, the value is 0, indicating the default packing size for the current platform. Der Wert Pack muss 0, 1, 2, 4, 8, 16, 32, 64 oder 128 lauten:The value of Pack must be 0, 1, 2, 4, 8, 16, 32, 64, or 128:

Die Felder einer Typinstanz werden mithilfe der folgenden Regeln ausgerichtet:The fields of a type instance are aligned by using the following rules:

  • Die Ausrichtung des Typs entspricht der Größe des größten Elements (1, 2, 4, 8 usw., Bytes) oder der angegebenen Komprimierungs Größe, je nachdem, welcher Wert kleiner ist.The alignment of the type is the size of its largest element (1, 2, 4, 8, etc., bytes) or the specified packing size, whichever is smaller.

  • Jedes Feld muss sich an Feldern seiner eigenen Größe (1, 2, 4, 8 usw., Bytes) oder der Ausrichtung des Typs ausrichten, je nachdem, welcher Wert kleiner ist.Each field must align with fields of its own size (1, 2, 4, 8, etc., bytes) or the alignment of the type, whichever is smaller. Da die Standardausrichtung des Typs die Größe des größten Elements ist, das größer als oder gleich allen anderen Feldlängen ist, bedeutet dies in der Regel, dass die Felder nach ihrer Größe ausgerichtet werden.Because the default alignment of the type is the size of its largest element, which is greater than or equal to all other field lengths, this usually means that fields are aligned by their size. Wenn z. b. das größte Feld in einem Typ eine 64-Bit-Ganzzahl (8 Byte) oder das Feld "Pack" auf 8 festgelegt ist, Byte Felder an 1-Byte-Begrenzungen ausgerichtet sind Int16 Felder an 2-Byte-Begrenzungen ausgerichtet und Int32 Felder an 4-Byte-Grenzen ausgerichtet.For example, even if the largest field in a type is a 64-bit (8-byte) integer or the Pack field is set to 8, Byte fields align on 1-byte boundaries, Int16 fields align on 2-byte boundaries, and Int32 fields align on 4-byte boundaries.

  • Die Auffüll Zeichen werden zwischen Feldern hinzugefügt, um die Ausrichtungs Anforderungen zu erfüllen.Padding is added between fields to satisfy the alignment requirements.

Sehen Sie sich beispielsweise die folgende Struktur an, die aus zwei Byte Feldern und einem Int32 Feld besteht, wenn es mit verschiedenen Werten für das Pack Feld verwendet wird.For example, consider the following structure, which consists of two Byte fields and one Int32 field, when it is used with various values for the Pack field.

using System;

struct ExampleStruct
{
   public byte b1;
   public byte b2;
   public int i3;
}

Important

Um die C# Beispiele erfolgreich zu kompilieren, müssen Sie den /unsafe-Compilerschalter angeben.To successfully compile the C# examples, you must specify the /unsafe compiler switch.

Wenn Sie die Standard Packgröße angeben, beträgt die Größe der Struktur 8 Bytes.If you specify the default packing size, the size of the structure is 8 bytes. Die zwei Bytes belegen die ersten zwei Bytes des Arbeitsspeichers, da Bytes an den einzelnen Byte Grenzen ausgerichtet werden müssen.The two bytes occupy the first two bytes of memory, because bytes must align on one-byte boundaries. Da die Standardausrichtung des Typs 4 Bytes ist, d. h. die Größe der größten Felder, i3, gibt es zwei Byte Auffüll Zeichen, gefolgt vom ganzzahligen Feld.Because the default alignment of the type is 4 bytes, which is the size of its largest fields, i3, there are two bytes of padding followed by the integer field.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack=0)]
struct ExampleStruct
{
   public byte b1;
   public byte b2;
   public int i3;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct ex = new ExampleStruct();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
   }
}
// The example displays the following output:
//       Size:      8
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 4

Wenn Pack auf 2 festgelegt ist, beträgt die Größe der Struktur 6 Bytes.If Pack is set to 2, the size of the structure is 6 bytes. Wie zuvor belegen die beiden Bytes die ersten zwei Bytes im Arbeitsspeicher.As before, the two bytes occupy the first two bytes of memory. Da Felder nun an 2-Byte-Begrenzungen ausgerichtet sind, gibt es keine Auffüll Zeichen zwischen dem zweiten Byte und der ganzen Zahl.Because fields now align on 2-byte boundaries, there is no padding between the second byte and the integer.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack=2)]
struct ExampleStruct
{
   public byte b1;
   public byte b2;
   public int i3;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct ex = new ExampleStruct();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
   }
}
// The example displays the following output:
//       Size:      6
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 2

Wenn Pack auf 4 festgelegt ist, entspricht die Größe der Struktur dem Standardfall, wobei die Ausrichtung des Typs durch die Größe des größten Felds definiert wurde, i3, d. h. 4.If Pack is set to 4, the size of the structure is the same as in the default case, where the type's alignment was defined by the size of its largest field, i3, which is 4.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack=4)]
struct ExampleStruct
{
   public byte b1;
   public byte b2;
   public int i3;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct ex = new ExampleStruct();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
   }
}
// The example displays the following output:
//       Size:      8
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 4

Wenn Pack auf 8 festgelegt ist, ist die Größe der-Struktur gleich wie im Standardfall, da das i3 Feld an einer 4-Byte-Begrenzung ausgerichtet ist, die kleiner als die durch das Pack-Feld angegebene 8-Byte-Grenze ist.If Pack is set to 8, the size of the structure is the still same as in the default case, because the i3 field aligns on a 4-byte boundary, which is smaller than the 8-byte boundary specified by the Pack field.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack=8)]
struct ExampleStruct
{
   public byte b1;
   public byte b2;
   public int i3;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct ex = new ExampleStruct();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
   }
}
// The example displays the following output:
//       Size:      8
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 4

Wenn Sie ein weiteres Beispiel verwenden möchten, betrachten Sie die folgende Struktur, die aus zwei Byte Feldern, einem 1 32-Bit-Ganzzahl-Feld mit Vorzeichen, einem Einzelelement-Bytearray und einem Dezimalwert besteht.To take another example, consider the following structure, which consists of two byte fields, one 32-bit signed integer field, one single-element byte array, and a decimal value. Bei der Standard Komprimierungs Größe beträgt die Größe der Struktur 28 bytes.With the default packing size, the size of the structure is 28 bytes. Die zwei Bytes belegen die ersten zwei Bytes des Arbeitsspeichers, gefolgt von zwei Byte Auffüll Zeichen, gefolgt von der ganzen Zahl.The two bytes occupy the first two bytes of memory, followed by two bytes of padding, followed by the integer. Der nächste Schritt ist das 1-Byte-Array, gefolgt von drei Byte Auffüll Zeichen.Next is the one-byte array, followed by three bytes of padding. Zum Schluss richtet sich das Decimal Feld D5 an einer 4-Byte-Grenze, da ein Dezimalwert aus vier Int32 Feldern besteht. seine Ausrichtung basiert also auf der Größe der größten seiner Felder, nicht auf der Größe der Decimal Struktur als Ganzes.Finally, the Decimal field, d5, aligns on a 4-byte boundary because a decimal value consists of four Int32 fields, so its alignment is based on the size of the largest of its fields rather than on the size of the Decimal structure as a whole.

using System;
using System.Runtime.InteropServices;

unsafe struct ExampleStruct2
{

   public byte b1;
   public byte b2;
   public int i3;
   public fixed byte a4[1];
   public decimal d5;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct2 ex = new ExampleStruct2();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct2));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
      Console.WriteLine("a4 Offset: {0}", ex.a4 - addr);
      Console.WriteLine("d5 Offset: {0}", (byte*) &ex.d5 - addr);
   }
}
// The example displays the following output:
//       Size:      28
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 4
//       a4 Offset: 8
//       d5 Offset: 12

Wenn Pack auf 2 festgelegt ist, beträgt die Größe der Struktur 24 Bytes.If Pack is set to 2, the size of the structure is 24 bytes. Im Vergleich zur Standardausrichtung wurden die zwei Bytes der Auffüll Zeichen zwischen den beiden Bytes und der ganzen Zahl entfernt, da die Ausrichtung des Typs jetzt 4 anstelle von 2 ist.In comparison with the default alignment, the two bytes of padding between the two bytes and the integer have been removed because the type's alignment is now 4 rather than 2. Und die drei Byte der Auffüll Zeichen nach dem a4 durch ein Byte von Auffüll Zeichen ersetzt wurden, da d5 nun an einer 2-Byte-Grenze und nicht an einer 4-Byte-Begrenzung ausgerichtet ist.And the three bytes of padding after a4 have been replaced by one byte of padding, since d5 now aligns on a 2-byte boundary rather than a 4-byte boundary.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 2)]
unsafe struct ExampleStruct2
{

   public byte b1;
   public byte b2;
   public int i3;
   public fixed byte a4[1];
   public decimal d5;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct2 ex = new ExampleStruct2();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct2));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
      Console.WriteLine("a4 Offset: {0}", ex.a4 - addr);
      Console.WriteLine("d5 Offset: {0}", (byte*) &ex.d5 - addr);
   }
}
// The example displays the following output:
//       Size:      24
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 2
//       a4 Offset: 6
//       d5 Offset: 8

Wenn Pack auf 8 festgelegt ist, entspricht die Größe der Struktur dem Standardfall, da alle Ausrichtungs Anforderungen in dieser Struktur kleiner als 8 sind.If Pack is set to 8, the size of the structure is the same as in the default case, because all the alignment requirements in this structure are less than 8.

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 8)]
unsafe struct ExampleStruct2
{

   public byte b1;
   public byte b2;
   public int i3;
   public fixed byte a4[1];
   public decimal d5;
}

public class Example
{
   public unsafe static void Main()
   {

      ExampleStruct2 ex = new ExampleStruct2();
      byte* addr = (byte*) &ex;
      Console.WriteLine("Size:      {0}", sizeof(ExampleStruct2));
      Console.WriteLine("b1 Offset: {0}", &ex.b1 - addr);
      Console.WriteLine("b2 Offset: {0}", &ex.b2 - addr);
      Console.WriteLine("i3 Offset: {0}", (byte*) &ex.i3 - addr);
      Console.WriteLine("a4 Offset: {0}", ex.a4 - addr);
      Console.WriteLine("d5 Offset: {0}", (byte*) &ex.d5 - addr);
   }
}
// The example displays the following output:
//       Size:      28
//       b1 Offset: 0
//       b2 Offset: 1
//       i3 Offset: 4
//       a4 Offset: 8
//       d5 Offset: 12

Das Pack Feld wird häufig verwendet, wenn Strukturen bei Datenträger-und Netzwerk Schreibvorgängen exportiert werden.The Pack field is frequently used when structures are exported during disk and network write operations. Das Feld wird auch häufig bei Platt Form aufrufen und Interop-Vorgängen verwendet.The field is also frequently used during platform invoke and interop operations.

Gelegentlich wird das-Feld verwendet, um die Arbeitsspeicher Anforderungen zu reduzieren, indem eine strengere Verpackungsgröße erzeugt wird.Occasionally, the field is used to reduce memory requirements by producing a tighter packing size. Diese Verwendung erfordert jedoch eine sorgfältige Überlegung tatsächlicher Hardware Einschränkungen und beeinträchtigt möglicherweise die Leistung.However, this usage requires careful consideration of actual hardware constraints, and may actually degrade performance.

Applies to