StructLayoutAttribute.Pack StructLayoutAttribute.Pack StructLayoutAttribute.Pack StructLayoutAttribute.Pack Field

Definición

Controla la alineación de los campos de datos de una clase o una estructura en la memoria.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 

Valor de campo

Comentarios

El Pack campo controla la alineación de los campos de un tipo en la memoria.The Pack field controls the alignment of a type's fields in memory. Afecta tanto LayoutKind.Sequential a como LayoutKind.Explicita.It affects both LayoutKind.Sequential and LayoutKind.Explicit. De forma predeterminada, el valor es 0, que indica el tamaño de empaquetado predeterminado para la plataforma actual.By default, the value is 0, indicating the default packing size for the current platform. El valor de Pack debe ser 0, 1, 2, 4, 8, 16, 32, 64 o 128:The value of Pack must be 0, 1, 2, 4, 8, 16, 32, 64, or 128:

Los campos de una instancia de tipo se alinean mediante las siguientes reglas:The fields of a type instance are aligned by using the following rules:

  • La alineación del tipo es el tamaño de su elemento más grande (1, 2, 4, 8, etc., bytes) o el tamaño de empaquetado especificado, lo que sea menor.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.

  • Cada campo debe estar alineado con campos de su propio tamaño (1, 2, 4, 8, etc., bytes) o la alineación del tipo, lo que sea menor.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. Dado que la alineación predeterminada del tipo es el tamaño de su elemento más grande, que es mayor o igual que el resto de longitudes de campo, esto suele significar que los campos se alinean por su tamaño.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. Por ejemplo, incluso si el campo más grande de un tipo es un entero de 64 bits (8 bytes) o el campo Pack se establece en 8, Byte los campos se alinean en límites de Int16 1 byte, los campos se alinean en Int32 límites de 2 bytes y los campos se alinean en límites de 4 bytes.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.

  • El relleno se agrega entre campos para satisfacer los requisitos de alineación.Padding is added between fields to satisfy the alignment requirements.

Por ejemplo, considere la siguiente estructura, que consta de dos Byte campos y un Int32 campo, cuando se utiliza con varios valores para el Pack campo.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;
}

Importante

Para compilar C# correctamente los ejemplos, debe especificar /unsafe el modificador del compilador.To successfully compile the C# examples, you must specify the /unsafe compiler switch.

Si especifica el tamaño de empaquetado predeterminado, el tamaño de la estructura es de 8 bytes.If you specify the default packing size, the size of the structure is 8 bytes. Los dos bytes ocupan los primeros dos bytes de memoria, ya que los bytes deben alinearse en los límites de un byte.The two bytes occupy the first two bytes of memory, because bytes must align on one-byte boundaries. Dado que la alineación predeterminada del tipo es 4 bytes, que es el tamaño de sus campos más grandes i3,, hay dos bytes de relleno seguidos por el campo de entero.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

Si Pack se establece en 2, el tamaño de la estructura es de 6 bytes.If Pack is set to 2, the size of the structure is 6 bytes. Como antes, los dos bytes ocupan los dos primeros bytes de memoria.As before, the two bytes occupy the first two bytes of memory. Dado que los campos ahora se alinean en límites de 2 bytes, no hay ningún relleno entre el segundo byte y el entero.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

Si Pack está establecido en 4, el tamaño de la estructura es el mismo que en el caso predeterminado, donde la alineación del tipo se definió con el tamaño de su campo más i3grande,, que es 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

Si Pack se establece en 8, el tamaño de la estructura es el mismo que en el caso predeterminado, ya que el i3 campo se alinea en un límite de 4 bytes, que es menor que el límite de 8 bytes especificado por el campo Pack.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

Para tomar otro ejemplo, considere la siguiente estructura, que consta de dos campos de byte, un campo de entero con signo de 1 32 bits, una matriz de bytes de un solo elemento y un valor decimal.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. Con el tamaño de empaquetado predeterminado, el tamaño de la estructura es de 28 bytes.With the default packing size, the size of the structure is 28 bytes. Los dos bytes ocupan los primeros dos bytes de memoria, seguidos de dos bytes de relleno, seguidos del entero.The two bytes occupy the first two bytes of memory, followed by two bytes of padding, followed by the integer. A continuación se encuentra la matriz de un byte, seguida de tres bytes de relleno.Next is the one-byte array, followed by three bytes of padding. Por último, Decimal el campo, D5, se alinea en un límite de 4 bytes porque un valor decimal consta Int32 de cuatro campos, por lo que su alineación se basa en el tamaño del mayor de sus campos, en lugar de Decimal en el tamaño de la estructura en su conjunto.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

Si Pack se establece en 2, el tamaño de la estructura es de 24 bytes.If Pack is set to 2, the size of the structure is 24 bytes. En comparación con la alineación predeterminada, los dos bytes de relleno entre los dos bytes y el entero se han quitado porque la alineación del tipo ahora es 4 en lugar de 2.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. Y los tres bytes de relleno después a4 de haber sido reemplazados por un byte de relleno d5 , ya que ahora se alinea en un límite de 2 bytes en lugar de un límite de 4 bytes.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

Si Pack se establece en 8, el tamaño de la estructura es el mismo que en el caso predeterminado, ya que todos los requisitos de alineación de esta estructura son menores que 8.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

El Pack campo se usa con frecuencia cuando se exportan estructuras durante las operaciones de escritura de disco y de red.The Pack field is frequently used when structures are exported during disk and network write operations. El campo también se usa con frecuencia durante las operaciones de interoperabilidad e invocación de plataforma.The field is also frequently used during platform invoke and interop operations.

En ocasiones, el campo se utiliza para reducir los requisitos de memoria al generar un tamaño de empaquetado más estrecho.Occasionally, the field is used to reduce memory requirements by producing a tighter packing size. Sin embargo, este uso requiere una consideración cuidadosa de las restricciones de hardware reales y, en realidad, puede degradar el rendimiento.However, this usage requires careful consideration of actual hardware constraints, and may actually degrade performance.

Se aplica a