StructLayoutAttribute.Pack Campo
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Controlla l'allineamento dei campi dati di una classe o una struttura nella memoria.
public: int Pack;
public int Pack;
val mutable Pack : int
Public Pack As Integer
Valore del campo
Commenti
Il Pack campo controlla l'allineamento dei campi di un tipo in memoria. Influisce su LayoutKind.Sequential. Per impostazione predefinita, il valore è 0, che indica le dimensioni predefinite per la piattaforma corrente. Il valore di Pack deve essere 0, 1, 2, 4, 8, 16, 32, 64 o 128:
I campi di un'istanza di tipo sono allineati usando le regole seguenti:
L'allineamento del tipo è la dimensione dell'elemento più grande (1, 2, 4, 8, ecc., byte) o la dimensione di imballaggio specificata, che tuttavia è più piccola.
Ogni campo deve essere allineato ai campi delle proprie dimensioni (1, 2, 4, 8, ecc., byte) o all'allineamento del tipo, che tuttavia è più piccolo. Poiché l'allineamento predefinito del tipo è la dimensione dell'elemento più grande, maggiore o uguale a tutte le altre lunghezze del campo, questo significa in genere che i campi sono allineati alle relative dimensioni. Ad esempio, anche se il campo più grande in un tipo è un intero a 64 bit (8 byte) o il campo Pack è impostato su 8, i campi si allineano su limiti a 1 byte, ByteInt16 i campi si allineano su limiti a 2 byte e Int32 i campi si allineano su limiti a 4 byte.
La spaziatura interna viene aggiunta tra i campi per soddisfare i requisiti di allineamento.
Si consideri ad esempio la struttura seguente, costituita da due Byte campi e un Int32 campo, quando viene usato con vari valori per il Pack campo.
using System;
struct ExampleStruct
{
public byte b1;
public byte b2;
public int i3;
}
Importante
Per compilare correttamente gli esempi C#, è necessario specificare l'opzione del /unsafe
compilatore.
Se si specificano le dimensioni predefinite della confezione, la dimensione della struttura è di 8 byte. I due byte occupano i primi due byte di memoria, perché i byte devono essere allineati ai limiti di un byte. Poiché l'allineamento predefinito del tipo è 4 byte, ovvero la dimensione dei campi più grandi, i3
sono presenti due byte di spaziatura interna seguita dal campo integer.
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
Se Pack è impostato su 2, le dimensioni della struttura sono 6 byte. Come prima, i due byte occupano i primi due byte di memoria. Poiché i campi ora si allineano su limiti a 2 byte, non esiste alcuna spaziatura interna tra il secondo byte e l'intero.
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
Se Pack è impostato su 4, la dimensione della struttura è uguale al caso predefinito, in cui l'allineamento del tipo è stato definito dalle dimensioni del campo più grande, i3
, che è 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
Se Pack è impostato su 8, la dimensione della struttura è uguale al caso predefinito, perché il i3
campo si allinea su un limite a 4 byte, minore del limite di 8 byte specificato dal campo Pack.
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
Per prendere un altro esempio, prendere in considerazione la struttura seguente, costituita da due campi di byte, un campo intero con segno a 32 bit, una matrice di byte a un singolo elemento e un valore decimale. Con le dimensioni predefinite dell'imballaggio, la dimensione della struttura è di 28 byte. I due byte occupano i primi due byte di memoria, seguiti da due byte di spaziatura interna, seguiti dall'intero. Successivamente è la matrice a un byte, seguita da tre byte di spaziatura interna. Infine, il Decimal campo, d5, si allinea su un limite di 4 byte perché un valore decimale è costituito da quattro Int32 campi, quindi l'allineamento è basato sulle dimensioni dei campi più grandi anziché sulle dimensioni della Decimal struttura nel suo complesso.
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
Se Pack è impostato su 2, le dimensioni della struttura sono 24 byte. Rispetto all'allineamento predefinito, i due byte di spaziatura tra i due byte e l'intero sono stati rimossi perché l'allineamento del tipo è ora 4 anziché 2. E i tre byte di spaziatura interna dopo a4
essere stati sostituiti da un byte di riempimento, poiché d5
ora si allinea su un limite a 2 byte anziché su un limite di 4 byte.
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
Se Pack è impostato su 8, le dimensioni della struttura sono uguali al caso predefinito, perché tutti i requisiti di allineamento in questa struttura sono inferiori a 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
Il Pack campo viene spesso usato quando le strutture vengono esportate durante operazioni di scrittura su disco e di rete. Il campo viene usato spesso anche durante le operazioni di richiamo e interoperabilità della piattaforma.
In alcuni casi, il campo viene usato per ridurre i requisiti di memoria generando una dimensione di imballaggio più stretta. Tuttavia, questo utilizzo richiede un'attenta considerazione dei vincoli hardware effettivi e può effettivamente ridurre le prestazioni.
Si applica a
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per