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

定義

メモリ内のクラスまたは構造体のデータ フィールドのアライメントを制御します。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 

フィールド値

注釈

Packフィールドがメモリ内の型のフィールドのアラインメントを制御します。The Pack field controls the alignment of a type's fields in memory. 両方に影響LayoutKind.SequentialLayoutKind.Explicitします。It affects both LayoutKind.Sequential and LayoutKind.Explicit. 既定では、値は、既定のパッキング サイズは現在のプラットフォームを示す、0 が。By default, the value is 0, indicating the default packing size for the current platform. Pack0、1、2、4、8、16、32、64、または 128 にする必要があります。The value of Pack must be 0, 1, 2, 4, 8, 16, 32, 64, or 128:

型のインスタンスのフィールドを配置するには、次の規則を使用しています。The fields of a type instance are aligned by using the following rules:

  • 型のアラインメントは、最大の要素のサイズになります (1、2、4、8、バイト) または指定したパッキング サイズの小さい方します。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.

  • 各フィールドは、独自のサイズのフィールドを連携する必要があります (1、2、4、8 などのバイト数) または型のアラインメント小さい方です。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. 型の既定の配置がその他のすべてのフィールドの長さ以上、その最大の要素のサイズであるため、つまり、通常のサイズを使用してフィールドを配置することです。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. 8 場合でも、型の最大サイズのフィールドは、64 ビット (8 バイト) の整数またはパック フィールドを設定するなど、Byteフィールドが 1 バイト境界に合わせて配置Int16フィールドが 2 バイト境界に合わせて配置とInt32フィールドは、4 バイト境界に配置します。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.

  • アラインメントの要件を満たすためにフィールドの間の余白が追加されます。Padding is added between fields to satisfy the alignment requirements.

たとえば、次の構造は、2 つから成るByteフィールドと 1 つInt32フィールドに、さまざまな値と共に使用するときに、Packフィールド。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;
}

重要

C# の例を正常にコンパイルすることを指定する必要があります、/unsafeコンパイラ スイッチ。To successfully compile the C# examples, you must specify the /unsafe compiler switch.

既定のパッキング サイズを指定すると、構造体のサイズは 8 バイトになります。If you specify the default packing size, the size of the structure is 8 bytes. 2 バイトは、バイトが 1 バイト境界に合わせて配置する必要がありますので、最初の 2 バイトのメモリを占有します。The two bytes occupy the first two bytes of memory, because bytes must align on one-byte boundaries. 型の既定の配置は 4 バイトで、その最大フィールドのサイズであるため、 i3、2 つのバイトの整数フィールドの後に埋め込みがあります。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

場合Pack設定が 2 には、構造体のサイズは 6 バイトです。If Pack is set to 2, the size of the structure is 6 bytes. としてする前に、2 つのバイトを占有するメモリの最初の 2 バイト。As before, the two bytes occupy the first two bytes of memory. フィールドは、2 バイト境界に今すぐ配置、ために、2 番目のバイト、整数の間の余白はありません。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

場合Pack設定されている構造体のサイズでは 4 には、既定では、型の配置がその最大サイズのフィールドのサイズによって定義されていると同じi34 であります。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

場合Pack設定は、8、構造体のサイズが、まだのため、既定値と同じ場合、i3フィールドはパック フィールドで指定された 8 バイト境界より小さい 4 バイト境界に揃えて配置します。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

別の例を実行するには、次の構造は、2 バイト フィールド、1 つの 32 ビット符号付き整数フィールド、1 つの 1 つの要素のバイト配列、および 10 進値から成るを検討します。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. 既定のパッキング サイズでは、構造体のサイズは、28 バイトです。With the default packing size, the size of the structure is 28 bytes. 2 バイトは、最初の 2 バイトの 2 バイトの後に、整数の余白の後にメモリを占有します。The two bytes occupy the first two bytes of memory, followed by two bytes of padding, followed by the integer. 次には、3 バイトの余白の後に、1 バイトの配列。Next is the one-byte array, followed by three bytes of padding. 最後に、Decimalフィールド、d5 は、10 進値は 4 つの 4 バイト境界に配置Int32、アラインメントは、最大のサイズに基づいているため、フィールドのサイズではなく、そのフィールドのDecimal全体の構造体。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

場合Pack設定が 2 には、構造体のサイズは 24 バイトです。If Pack is set to 2, the size of the structure is 24 bytes. 既定の配置とは、2 バイト、整数の間の余白の 2 バイトを型のアラインメントが 2 ではなく 4 ために削除されています。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. 次の 3 つのバイトの後に埋め込みa4ため、埋め込みの 1 バイトに置き換えられているd5を 4 バイト境界ではなく、2 バイト境界に揃えるようになりました。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

場合Pack設定は、8、構造体のサイズと同じ既定では、この構造体のすべてのアラインメント要件は 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

Packフィールドは、ディスクの中に構造体がエクスポートされ、ネットワーク書き込み操作時に頻繁に使用します。The Pack field is frequently used when structures are exported during disk and network write operations. フィールドは、プラットフォームの中には使用も頻繁に呼び出すと相互運用機能の操作。The field is also frequently used during platform invoke and interop operations.

場合によっては、フィールドは、厳密なパッキング サイズを生成することのメモリ要件の縮小に使用されます。Occasionally, the field is used to reduce memory requirements by producing a tighter packing size. ただし、この使用法は、実際のハードウェアの制約の慎重に検討する必要があります、実際にパフォーマンスが低下する可能性があります。However, this usage requires careful consideration of actual hardware constraints, and may actually degrade performance.

適用対象