.NET中结构的大小

use*_*830 9 .net interop struct

我的问题是在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
}
Run Code Online (Sandbox Code Playgroud)

结构的总大小必须是20个字节.

当我用sizeof()这种结构的C++ 做的时候,

System.Diagnostics.Debug.WriteLine(
    "SizeOf(NetPoint) = " +
    System.Runtime.InteropServices.Marshal.SizeOf(new NetPoint()));
Run Code Online (Sandbox Code Playgroud)

调试控制台显示:

SizeOf(NetPoint)= 24

但我预计会有20个字节.为什么我看到了区别?

Joh*_*ler 9

作为一般规则,CPU喜欢将变量在内存中对齐,其位置是其大小的偶数倍,因此四字节整数应位于可被4整除的内存地址上,并且long应为8字节在一个可被8整除的地址.

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
}
Run Code Online (Sandbox Code Playgroud)

您可以通过将long设为第一个值来解决此问题,通常,如果始终将最大值放在结构的开头,则不会插入任何填充以保持成员的对齐.

您也可以通过添加来修复它

[StructLayout(LayoutKind.Sequential, Pack = 4)]
Run Code Online (Sandbox Code Playgroud)

在结构声明之前,但这将导致错误对齐long time,从而损害性能.在某些CPU上,它会对性能造成很大的伤害.(例如,ALPHA AXP会因未对齐的成员而出错).x86 CPU的性能损失很小,但是未来的CPU存在着性能损失的危险,因此如果可以的话,最好将结构设计得恰当(而不是打包).


小智 7

实际上,从技术上讲,结构必须至少为20个字节.如果在发送时分配更多,接收器就不会使用/复制它们.问题始终是低位.

那就是说,我看到了问题.嗯.我认为问题是最后一段时间......恕我直言的八个字节对齐,之前注入四个空字节.我认为将8字节元素与8字节边界对齐会产生性能损失.

附加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 
} 
Run Code Online (Sandbox Code Playgroud)

至少应该将元素对齐到一个字节的边界.如果需要,您还可以通过定义每个元素的确切开始来进一步说明.