StructLayoutAttribute.Pack Alan

Tanım

Bellekteki bir sınıfın veya yapının veri alanlarının hizalamasını denetler.

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

Alan Değeri

Açıklamalar

alan, Pack bellekteki bir türün alanlarının hizalamasını denetler. bu, 'yi LayoutKind.Sequentialetkiler. Varsayılan olarak, geçerli platform için varsayılan paketleme boyutunu gösteren değer 0'dır. değeri Pack 0, 1, 2, 4, 8, 16, 32, 64 veya 128 olmalıdır:

Bir tür örneğinin alanları aşağıdaki kurallar kullanılarak hizalanır:

  • Türün hizalaması, en büyük öğesinin boyutu (1, 2, 4, 8, vb., bayt) veya belirtilen paketleme boyutudur (hangisi daha küçükse).

  • Her alan kendi boyutundaki alanlarla (1, 2, 4, 8, vb., bayt) veya türün hizalamasıyla (hangisi daha küçükse) hizalanmalıdır. Türün varsayılan hizalaması, diğer tüm alan uzunluklarından büyük veya buna eşit olan en büyük öğesinin boyutu olduğundan, bu genellikle alanların boyutlarına göre hizalandığı anlamına gelir. Örneğin, bir türdeki en büyük alan 64 bit (8 bayt) bir tamsayı olsa veya Paket alanı 8 olarak ayarlanmış olsa bile, Byte alanlar 1 baytlık sınırlara hizalanır, Int16 alanlar 2 baytlık sınırlara hizalanır ve Int32 alanlar 4 baytlık sınırlara hizalanır.

  • Hizalama gereksinimlerini karşılamak için alanlar arasına doldurma eklenir.

Örneğin, alan için çeşitli değerlerle kullanıldığında iki Byte alandan ve bir Int32 alandan oluşan aşağıdaki yapıyı Pack göz önünde bulundurun.

using System;

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

Önemli

C# örneklerini başarıyla derlemek için derleyici anahtarını belirtmeniz /unsafe gerekir.

Varsayılan paketleme boyutunu belirtirseniz, yapının boyutu 8 bayttır. Baytların tek baytlık sınırlara hizalanmış olması gerektiğinden, iki bayt belleğin ilk iki baytını kaplar. Türün varsayılan hizalaması en büyük alanlarının boyutu olan 4 bayt olduğundan, i3iki bayt doldurma ve ardından tamsayı alanı vardır.

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

2 olarak ayarlanırsa Pack , yapının boyutu 6 bayttır. Daha önce olduğu gibi, iki bayt belleğin ilk iki baytını kaplar. Alanlar artık 2 baytlık sınırlara hizalandığından, ikinci bayt ile tamsayı arasında doldurma yoktur.

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

4 olarak ayarlanırsa Pack , yapının boyutu varsayılan durumdakiyle aynıdır; burada türün hizalaması en büyük alanı i3olan 4'ün boyutuyla tanımlanmıştır.

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

8 olarak ayarlanırsa Pack , alan Pack alanı tarafından belirtilen 8 baytlık sınırdan daha küçük olan 4 baytlık bir sınıra hizalandığından, yapının boyutu varsayılan durumdakiyle i3 aynıdır.

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

Başka bir örnek almak için, iki bayt alanı, bir 32 bit imzalı tamsayı alanı, bir tek öğeli bayt dizisi ve ondalık değerden oluşan aşağıdaki yapıyı göz önünde bulundurun. Varsayılan paketleme boyutuyla, yapının boyutu 28 bayttır. İki bayt, belleğin ilk iki baytını, ardından iki bayt doldurmayı ve ardından tamsayıyı kaplar. Sonraki, bir baytlık dizi ve ardından üç bayt doldurmadır. Son olarak, Decimal d5 alanı 4 baytlık bir sınıra hizalanır çünkü ondalık değer dört Int32 alandan oluşur, bu nedenle hizalaması bir bütün olarak yapının boyutu yerine alanlarının en büyük boyutunu Decimal temel alır.

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

2 olarak ayarlanırsa Pack , yapının boyutu 24 bayttır. Varsayılan hizalamaya kıyasla, türün hizalaması artık 2 yerine 4 olduğundan, iki bayt ile tamsayı arasındaki iki doldurma baytları kaldırılmıştır. Sonrasındaki üç bayt doldurma a4 bir bayt doldurma ile değiştirilmiştir, çünkü d5 artık 4 baytlık bir sınır yerine 2 baytlık bir sınıra hizalanır.

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

8 olarak ayarlanırsa Pack , bu yapıdaki tüm hizalama gereksinimleri 8'den küçük olduğundan, yapının boyutu varsayılan durumdakiyle aynıdır.

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

Alan Pack genellikle disk ve ağ yazma işlemleri sırasında yapılar dışarı aktarıldığında kullanılır. Bu alan ayrıca platform çağırma ve birlikte çalışma işlemleri sırasında da sık kullanılır.

Bazen alan, daha sıkı bir paketleme boyutu üreterek bellek gereksinimlerini azaltmak için kullanılır. Ancak, bu kullanım gerçek donanım kısıtlamalarının dikkatli bir şekilde dikkate alınmasını gerektirir ve performansı düşürebilir.

Şunlara uygulanır