首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >.NET中的结构尺寸

.NET中的结构尺寸
EN

Stack Overflow用户
提问于 2010-03-11 19:51:20
回答 4查看 809关注 0票数 9

我的问题是在C中的程序之间发送一个结构到一个C#程序。

我在C#中创建了一个结构:

代码语言:javascript
运行
复制
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++时,

代码语言:javascript
运行
复制
System.Diagnostics.Debug.WriteLine(
    "SizeOf(NetPoint) = " +
    System.Runtime.InteropServices.Marshal.SizeOf(new NetPoint()));

调试控制台显示:

SizeOf(NetPoint) = 24

但我想有20个字节。为什么我看到了不同的地方?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-03-11 19:58:51

实际上,从技术上讲,这个结构必须是20字节的最小。如果在发送时分配更多,接收方就不会使用/复制它们。问题总是分配不足。

尽管如此,我看到了问题所在。嗯。我认为问题是最后一次.IMHO将其对齐为8个字节,在此之前注入4个空字节。我认为,如果一个8字节的元素与一个8字节的边界不对齐,就会造成性能损失。

附加StructLayout属性以手动确定每个元素的偏移量。那你就应该能把事情搞清楚了。

参考资料:http://support.microsoft.com/kb/922785

代码语言:javascript
运行
复制
[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 
} 

这至少应该使元素对齐到一个字节的边界。如果需要的话,您也可以通过定义每个元素的确切开始来更进一步。

票数 7
EN

Stack Overflow用户

发布于 2010-03-11 20:00:25

通常情况下,CPU喜欢将变量放在内存中大小为偶数倍的位置对齐,因此一个4字节的整数应该位于一个可被4整除的内存地址上,而一个8字节的long应该位于一个可被8整除的地址上。

C# (和C++)语言设计人员知道这一点,他们将在结构中插入填充以提供必要的对齐。结构的实际布局如下所示:

代码语言:javascript
运行
复制
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作为第一个值来解决这个问题,通常,如果您总是将最大的值放在结构的开头,那么就不会插入任何填充来保持成员对齐。

还可以通过添加

代码语言:javascript
运行
复制
[StructLayout(LayoutKind.Sequential, Pack = 4)]

在结构声明之前,但是这会导致错误对齐的long time,从而损害性能.在一些CPU上,这对性能影响很大。(例如,阿尔法AXP会对不对齐的成员造成错误)。x86 CPU的性能损失很小,但是将来CPU可能会有很大的性能损失,所以最好设计结构来正确地对齐(而不是打包它们)。

票数 10
EN

Stack Overflow用户

发布于 2010-03-11 19:55:50

尝试添加属性StructLayout(LayoutKind.Sequential,Pack = 1),看看会发生什么。我怀疑一个8字节的填充,所以它是3x8字节。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2428168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档