简体   繁体   English

这两种结构有什么区别

[英]What is the difference between these 2 structures

There are 2 ways I can define this structure which I wish to pass as an argument to a pinvoke function. 我可以通过两种方式定义这个结构,我希望将其作为参数传递给pinvoke函数。 I wanted to know what was the difference between the 2 我想知道2之间有什么区别

[StructLayout(LayoutKind.Sequential)]
public struct Rect {
   public int left;
   public int top;
   public int right;
   public int bottom;
}   

[StructLayout(LayoutKind.Explicit)]
public struct Rect {
   [FieldOffset(0)] public int left;
   [FieldOffset(4)] public int top;
   [FieldOffset(8)] public int right;
   [FieldOffset(12)] public int bottom;
}

From the definitions of layouts I found here , shouldnt both look the same in memory? 根据我在这里找到的布局定义,内存中的内容看起来不一样吗? Any advantages of one over the other? 一个优于另一个的任何优势?

From the definitions of layouts I found here, shouldn't both look the same in memory? 从我在这里找到的布局定义来看,内存中的内容不应该相同吗?

Yes, they will look the same in memory. 是的,它们在内存中看起来一样。

Any advantages of one over the other? 一个优于另一个的任何优势?

One's faster to type out, and is easier to read. 输入速度更快,更容易阅读。


The use of FieldOffset is of course a useful tool; FieldOffset的使用当然是一个有用的工具; it's not like it's always useless, but if you just so happen to use it to explicitly lay out the fields in the manor in which they would be laid out by default, then it's useless. 它不像它总是无用的,但是如果你恰好用它来明确地在庄园中布置它们将在默认情况下布局的字段,那么它就没用了。 If you use it to lay out fields in a manor other than their default value (for example, having the overlap, adding padding space, having the underlying representation be in a different order than the declaration order, etc.), then it's not useless. 如果您使用它来布置除默认值以外的庄园中的字段(例如,具有重叠,添加填充空间,使基础表示的顺序与声明顺序不同,等等),那么它就没用了。

In theory these two are exactly the same. 从理论上讲,这两者完全相同。 Typically you would use the explicit layout when you are interacting with non-managed code. 通常,在与非托管代码交互时,您将使用显式布局。 This can be important because in the future "int" might not have 32 bits in it - meaning that the sequential layout might no longer be applicable. 这可能很重要,因为将来“int”中可能没有32位 - 这意味着顺序布局可能不再适用。 Hopefully this helps a bit! 希望这有点帮助!

Edit 编辑

One more thought is if you were mapping a .NET structure to an unmanaged union or using different types in .NET than in unmanaged code this would be really useful. 还有一种想法是,如果您将.NET结构映射到非托管联合或使用.NET中的不同类型而非非托管代码,这将非常有用。

Second Edit 第二次编辑

Others have noted that MS will "never" change the size of an int. 其他人已经注意到MS将“永远不会”改变int的大小。 I can agree this would be a breaking change and it is therefore highly unlikely. 我同意这将是一个突破性的变化,因此不可能。 That said, being explicit about structure mapping when marshaling values between .NET and unmanaged code can still be a good idea. 也就是说,在.NET和非托管代码之间编组值时,明确关于结构映射仍然是个好主意。 This is especially true if there is a possibility of unmanaged structure/layout changing in the future. 如果将来可能出现未管理的结构/布局变化,则尤其如此。

I don't think that there is a real better layout version for this problem. 我不认为这个问题有更好的布局版本。 The second version with the Explicit LayoutKind though allows you to change the order of the structure's members as you indicate their position in the memory with the fieldoffest. 具有Explicit LayoutKind的第二个版本允许您在使用fieldoffest指示它们在内存中的位置时更改结构成员的顺序。 The second version is easier to expand in my opinion. 在我看来,第二个版本更容易扩展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM