何时应明确指定StructLayout?

6

我正在尝试从C#调用DLL,并需要定义自己的结构体。很多文章都要求对结构体进行顺序布局。

[StructLayout(LayoutKind.Sequential)]
struct Foo ...

所以,我跟随了这个套路,我的程序也成功运行了。现在,当我把这一行删除后,它仍然可以正常工作。为什么我还需要它?
3个回答

5

托管结构的内部布局是未记录和无法发现的。成员顺序和打包等实现细节是有意隐藏的。通过使用[StructLayout]属性,您可以强制P/Invoke marshaller施加特定的布局和打包。

默认情况下恰好匹配您需要使代码正常工作的布局只是一种偶然。虽然这并不罕见。请注意Type.StructLayoutAttribute属性。


1
谢谢你的回答。我刚刚查看了我的结构体的StructLayoutAttribute,有和没有那行代码都给了我sequential。这是默认值吗? - biozinc
3
这是一个老的答案,但也许值得注意的是它并不完全正确。代码没有属性正常工作的事实是由于默认情况下所有结构体都应用了LayoutKind.Sequential: MSDN:"C#,Visual Basic 和 C++编译器默认将顺序布局值应用于结构体。对于类,您必须显式地应用LayoutKind.Sequential值。(…)" - Sly

1

有趣的观点。我确信我曾经编写的代码在没有显式指定LayoutKind.Sequential时会失败,但是我已经确认即使在1.1中,Sequential也是结构体的默认值。

请注意VB结构体参考中的说明>行为>内存消耗,这意味着您需要指定StructLayout来确认内存布局,但StructLayoutAttribute的文档说明了Microsoft编译器中结构体的默认值是Sequential。


0

我不是完全确定,但它可能会影响二进制序列化 - 它可能会按顺序输出字段而没有命名或排序信息(导致文件更小),但这只是一种随意的想法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接