StructLayoutAttribute.Pack フィールド

定義

メモリ内のクラスまたは構造体のデータ フィールドのアライメントを制御します。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. の値はPack 、0、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. たとえば、型の最大のフィールドが64ビット (8 バイト) の整数である場合、またはパックのフィールドが 8 Byteに設定されている場合でも、1バイトの境界にフィールドが配置され、 Int32 Int16フィールドが2バイトの境界に配置され、フィールドが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. バイトは1バイトの境界に合わせて配置する必要があるため、2バイトは最初の2バイトのメモリを占有します。The two bytes occupy the first two bytes of memory, because bytes must align on one-byte boundaries. 型の既定の配置は、最大のフィールドi3のサイズである4バイトであるため、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 に設定されている場合、構造体のサイズは、既定のケースと同じです。この場合、型のアラインメントはi3、最大の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

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つの単一要素のバイト配列、および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. 次は1バイト配列で、その後に3バイトの余白が続きます。Next is the one-byte array, followed by three bytes of padding. 最後に、 Decimalこのフィールドは、4バイトの境界に配置されます。これは、10 Int32進値が4つのフィールドで構成されるためです。そのため、配置は、 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. との後a4の3バイトの埋め込みは、が4バイト境界ではd5なく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.

適用対象