Freigeben über


StructLayoutAttribute.Pack-Feld

 

Veröffentlicht: Oktober 2016

Steuert die Ausrichtung der Datenfelder einer Klasse oder Struktur im Speicher.

Namespace:   System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)

Syntax

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

Feldwert

Type: System.Int32

Hinweise

Die Pack Feld steuert die Ausrichtung der Felder im Arbeitsspeicher. Es wirkt sich auf beide LayoutKind.Sequential und LayoutKind.Explicit. Standardmäßig ist der Wert 0, gibt die Standardkomprimierungsgröße für die aktuelle Plattform. Der Wert des Pack muss 0, 1, 2, 4, 8, 16, 32, 64 oder 128 sein:

Die Felder einer Instanz des Typs werden ausgerichtet, mithilfe der folgenden Regeln:

  • Die Ausrichtung des Typs ist die Größe des größten Elements (1, 2, 4, 8 usw., Bytes) oder die angegebene Größe, je nachdem, was kleiner ist.

  • Jedes Feld muss Felder des eigenen Größe ausgerichtet (1, 2, 4, 8, usw., Bytes) oder die Ausrichtung des Typs, je nachdem, was kleiner ist. Ist die standardmäßige Ausrichtung des Typs der Größe des größten Elements, das größer als oder gleich alle anderen Feldlängen ist, bedeutet dies im Allgemeinen, dass Felder durch ihre Größe ausgerichtet sind. Angenommen, auch wenn das größte Feld in einem Typ eine 64-Bit-Ganzzahl (8 Byte) oder das Feld Pack ist auf 8 festgelegt ist Byte Ausrichten auf 1-Byte-Grenzen Int16 Felder auf 2-Byte-Grenzen ausgerichtet und Int32 Felder auf 4-Byte-Grenzen ausgerichtet.

  • Zwischen Feldern zu Ausrichtung Suchwerts hinzugefügt.

Betrachten Sie beispielsweise die folgende Struktur besteht aus zwei Byte -Felder und ein Int32 Feld bei Verwendung mit verschiedenen Werten für die Pack Feld.

using System;

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

Wichtig

Um den C#-Beispielen erfolgreich zu kompilieren, geben Sie die /unsafe -Compilerschalter.

Wenn Sie die Standardkomprimierungsgröße angeben, wird die Größe der Struktur 8 Bytes. Die zwei Bytes belegen die ersten zwei Bytes an Arbeitsspeicher, da Bytes an ein-Byte-Grenzen ausgerichtet werden müssen. Da die standardmäßige Ausrichtung des Typs 4 Bytes ist, wird die Größe des größten Felder i3, es gibt zwei Byte gefolgt von der Ganzzahlfeld Auffüllung.

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 festgelegt ist auf 2 wird die Größe der Struktur 6 Bytes. Belegen vor, die zwei Bytes die ersten zwei Bytes des Speichers. Da Felder nun an 2-Byte-Grenzen ausgerichtet werden, ist keine Leerstellen zwischen das zweite Byte und die ganze Zahl.

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 festgelegt ist auf 4, die Größe der Struktur gleicht der Standardfall, in den Typ Ausrichtung durch die Größe des größten Felds definiert wurde, i3, die 4 ist.

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 festgelegt ist auf 8 ist die Größe der Struktur immer noch anders als in der Standardeinstellung Fall, da die i3 Feld ausgerichtet auf eine 4-Byte-Grenze, die kleiner als die 8-Byte-Grenze, die vom Feld Pack angegeben ist.

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

Um ein weiteres Beispiel nutzen zu können, sollten Sie die folgende Struktur besteht aus zwei Byte-Feldern, eine 32-Bit-Ganzzahl mit Vorzeichen-Feld, ein Einzelelement-Byte-Array und einen decimal-Wert aus. Die Standardkomprimierungsgröße ist die Größe der Struktur 28 Bytes. Die zwei Bytes belegen die ersten zwei Bytes des Arbeitsspeichers, gefolgt von zwei Byte Auffüllung, gefolgt von der ganzen Zahl. Als Nächstes ist die 1-Byte-Array, gefolgt von drei Bytes Abstand. Schließlich die Decimal Feld d5, auf eine 4-Byte-Grenze ausgerichtet, da ein Dezimalwert aus vier besteht Int32 Felder, damit die Ausrichtung auf die Größe des größten basiert der zugehörigen Felder und nicht auf die Größe des der Decimal Struktur als Ganzes.

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 festgelegt ist auf 2 wird die Größe der Struktur 24 Bytes. Gegenüber der Standardeinstellung ausgerichtet wurden die zwei Bytes der Abstand zwischen den beiden Bytes und die ganze Zahl entfernt, da die Ausrichtung des Typs jetzt 4, sondern 2 ist. Und die drei Bytes Abstand nach a4 ersetzt wurden um ein Byte Abstand, da d5 jetzt auf eine 4-Byte-Grenze, statt eine 2-Byte-Grenze ausgerichtet.

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 festgelegt ist auf 8, die Größe der Struktur gleicht der Standardfall, da die ausrichtungsanforderungen in dieser Struktur kleiner als 8 sind.

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, während Datenträger-exportiert werden und Netzwerkschreibvorgängen. Dieses Feld wird auch häufig verwendet, während der Plattform aufrufen und Interop-Operationen.

Es kann vorkommen, wird das Feld Speicherbedarf zu verringern, so dass eine engere Komprimierungsgröße verwendet. Diese Verwendung erfordert eine sorgfältige Planung der tatsächlichen Hardware-Einschränkungen und kann tatsächlich die Leistung beeinträchtigen.

Versionsinformationen

Universelle Windows-Plattform
Verfügbar seit 8
.NET Framework
Verfügbar seit 1.1
Portierbare Klassenbibliothek
Unterstützt in: portierbare .NET-Plattformen
Silverlight
Verfügbar seit 2.0
Windows Phone Silverlight
Verfügbar seit 8.0
Windows Phone
Verfügbar seit 8.1

Siehe auch

StructLayoutAttribute-Klasse
System.Runtime.InteropServices-Namespace

Zurück zum Anfang