.NET 中結構的大小
我的問題是將 C 中的程序之間的結構發送到 C# 程序。
我在 C# 中創建了一個結構:
public struct NetPoint { public float lat; // 4 bytes public float lon; // 4 bytes public int alt; // 4 bytes public long time; // 8 bytes }結構的總大小必須為 20 字節。
當我
sizeof()在 C++ 中做這個結構時,System.Diagnostics.Debug.WriteLine( "SizeOf(NetPoint) = " + System.Runtime.InteropServices.Marshal.SizeOf(new NetPoint()));調試控制台顯示:
SizeOf(NetPoint) = 24
但我預計會有 20 個字節。為什麼我看到了不同?
實際上,從技術上講,該結構必須至少為 20 個字節。如果您在發送時分配更多,接收者就不會使用/複製它們。問題總是分配不足。
也就是說,我看到了問題。唔。我認為問題是最後一個長……恕我直言,它與八個字節對齊,之前註入了四個空字節。我認為八字節元素未與八字節邊界對齊會降低性能。
附加StructLayout屬性以手動確定每個元素的偏移量。然後,您應該能夠使事情井井有條。
參考:.NET Framework 2.0中如何控制數據域的物理佈局
[StructLayout(LayoutKind.Sequential, Pack=1)] public struct NetPoint { public float lat; // 4 bytes public float lon; // 4 bytes public int alt; // 4 bytes public long time; // 8 bytes }至少應該將元素對齊到一個字節的邊界。如果需要,您也可以通過定義每個元素的確切開始來更進一步。
作為一般規則,CPU 喜歡將變數在記憶體中對齊的位置是其大小的偶數倍,因此 4 字節整數應位於可被 4 整除的記憶體地址上,而 8 字節整數應位於可被 4 整除的記憶體地址上
long。在一個能被八整除的地址。C#(和 C++)語言設計者知道這一點,他們會在結構中插入填充以提供必要的對齊。所以你的結構的實際佈局如下所示:
public struct NetPoint { public float lat; // 4 bytes Offset 0 public float lon; // 4 bytes Offset 4 public int alt; // 4 bytes Offset 8 int to_preserve_alignment; // 4 bytes Offset 12 public long time; // 8 bytes Offset 16 }您可以通過將 long 作為第一個值來解決此問題,通常,如果您始終將最大值放在結構的開頭,則不會插入任何填充以保持成員的對齊。
您也可以通過添加來修復它
[StructLayout(LayoutKind.Sequential, Pack = 4)]在結構聲明之前,但這會導致錯位,
long time從而損害性能。在某些 CPU 上,它會嚴重影響性能。(例如,ALPHA AXP會在未對齊的成員上出錯)。x86 CPU 只有輕微的性能損失,但未來的 CPU 可能會面臨嚴重的性能損失,因此如果可以的話,最好將結構設計為正確對齊(而不是打包)。