StructLayoutAttribute.Pack Alan
Tanım
Önemli
Bazı bilgiler ürünün ön sürümüyle ilgilidir ve sürüm öncesinde önemli değişiklikler yapılmış olabilir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.
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, i3
iki 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ı i3
olan 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
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin