[StructLayout(LayoutKind.Sequential)]
unsafe struct B{
// public int field1;
public double field2;
public string field3;
byte* field4;
byte field5;
nint field6;
byte field7;
byte field8;
short field9;
short field10;
short field11;
// decimal field7;
}
sizeof(B)=48 ;
和LayoutKind.Auto的結果一樣的, 反覆試了幾遍感覺似乎和欄位的順序沒關係,開啟field1 的話,它還是會和別的不足一個pack的欄位接合。。 除非出現轉彎
那麼我來名詞解釋下,pack 就是說記憶體地址的長度,64位=8位元組在這樣的記憶體平臺上 pack=address length=8 byte , 在32位記憶體平臺上,是4 byte , C#記憶體對齊的規則 大致是這樣的,從office 0開始往後依次排,按address len來計算,只要多個欄位的長度相加沒出現“轉彎” 或 稱為“摺疊”那麼這種 多個欄位放入一個 address len(pack)之內的情況就是會發生的,應該是自動發生的,比方一個 byte 型別是 1,一個short 是2,一個 int是4 這些欄位都小於 memory address len 所以多個這樣的欄位可以放入一個 pack裡,並且這是自動的,但是若 一個Int + double這就不行,因為4+8 =12 已經大於一個pack =8了,所以出同現疊這就不允許 (這個規則 是我猜測的,是符合邏輯的推測)因為若出現各種摺疊則 讓欄位的讀取和識別將變得異常複雜 和困難
[StructLayout(LayoutKind.Sequential)] struct C1{ int filed1; double field2; short field3; } [StructLayout(LayoutKind.Auto)] struct C2{ int filed1; double field2; short field3; } [StructLayout(LayoutKind.Sequential)] struct C3{ int filed1; short field3; double field2; } [StructLayout(LayoutKind.Auto)] struct C4{ int filed1; short field3; double field2; } unsafe{ Console.WriteLine("Sequential,C1:int,double,short sizeof:{0}",sizeof(C1)); Console.WriteLine("Auto,C2:int,double,short sizeof:{0}",sizeof(C2)); Console.WriteLine("Sequential,C3:int,short,double sizeof:{0}",sizeof(C3)); Console.WriteLine("Auto,C4:int,short,double sizeof:{0}",sizeof(C4)); }
Sequential,C1:int,double,short sizeof:24
Auto,C2:int,double,short sizeof:16
Sequential,C3:int,short,double sizeof:16
Auto,C4:int,short,double sizeof:16
using System.Runtime.InteropServices; unsafe struct A{ public int field1; public double field2; public string field3; public int Field1 { get => field1; set => field1 = value; } public double Field2 { get => field2; set => field2 = value; } public void M1() => Console.WriteLine("M1"); } [StructLayout(LayoutKind.Sequential)] unsafe struct B{ public int field1; public double field2; public string field3; byte* field4; byte field5; nint field6; byte field7; byte field8; short field9; short field10; short field11; // decimal field7; } [StructLayout(LayoutKind.Auto)] unsafe struct B2{ public int field1; public double field2; public string field3; byte* field4; byte field5; nint field6; byte field7; byte field8; short field9; short field10; short field11; // decimal field7; } unsafe{ var x1=new A(); var p1 = &x1; p1->Field1=10; Console.WriteLine(x1.Field1); p1->M1(); Console.WriteLine(sizeof(A)); Console.WriteLine(sizeof(B)); Console.WriteLine(sizeof(B2)); }
10
M1
24
48
48
為什麼 sizeof(B) 和sizeof(B2) 都為48 沒搞懂,不應該說 sizeof(B) = 56嗎? 誰能解釋