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个字节.为什么我看到了区别?
作为一般规则,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)
至少应该将元素对齐到一个字节的边界.如果需要,您还可以通过定义每个元素的确切开始来进一步说明.