Anyone familiar with C/C ++ knows that members of the struct type are stored in sequence in the memory, that is, in the declared order of members, in addition, the alignment is usually performed based on the members that occupy the largest space among the members.
However, it is different in the. NET hosting environment. CLR provides two different memory layout modes for structural members: layoutkind. Sequential and layoutkind. explicit, which implement common sequential layout and precise layout by Offset respectively. The former is the default value of CLR. We can add the modifier [structlayout (layoutkind. Sequential)] When declaring struct to tell CLR to adopt the memory layout in order. Struct declared in this layout method is consistent with the struct declared in the memory and in the unmanaged environment. Therefore, struct should be declared in a sequential manner during interactive calling of unmanaged DLL. See the following example:
[Structlayout (layoutkind. Sequential)]
Struct S1 // 16 byte
{
Int I; // 4 bytes
Double B; // 8 bytes
}
Originally, S1 occupies only 12 bytes of memory. However, when we test sizeof (S1), we find that it actually occupies 16 bytes, this is because layoutkind. in sequential (default), the CLR treats struct layout in the same way as the default Processing Method in C/C ++, align ). Obviously, this method wastes a certain amount of memory space.
However, there are also some shortcomings in the layout by offset. When the offset calculation is inaccurate, data will be lost. See the following example:
[Structlayout (layoutkind. explicit)]
Struct S2
{
[Fieldoffset (0)] int I;
[Fieldoffset (0)] Double B;
}
In S2, the two Members have a memory offset of 0, which means they occupy the same part of the memory space. When one of the values is modified, the other value is also changed. Because the offset calculation should be very careful. The following is a good example on msnd:
Using system. runtime. interopservices;
[Structlayout (layoutkind. explicit, size = 16, charset = charset. ANSI)] Public Class Mysystemtime {[fieldoffset (0)] Public Ushort Wyear; [fieldoffset (2)] Public Ushort Wmonth; [fieldoffset (4)]Public Ushort Wdayofweek; [fieldoffset (6)] Public Ushort Wday; [fieldoffset (8)] Public Ushort Whour; [fieldoffset (10)] Public Ushort Wminute; [fieldoffset (12)] Public Ushort Wsecond; [fieldoffset (14)] Public Ushort Wmilliseconds ;}
Careful friends may find that:CodeThe class plane is used instead of struct, which indicates that there is no essential difference between class and struct. Let's look at a better example of using the sequence method:
[Structlayout (layoutkind. Sequential)]
Public struct point {
Public point (int xx, int YY) {x = xx; y = YY;} // Constructor
Public int X;
Public int y;
Public override string tostring (){
String S = string. Format ("({0}, {1})", x, y );
Return S;
}
}
Note:
In fact, there is a third Layout Method in. Net: [structlayout (layoutkind. Auto)]. In this way, the CLR will adjust the field order in the struct to occupy as little memory as possible. That is to say, the CLR will automatically rank the largest space occupied by struct, memory alignment with a small footprint and 4 byte alignment can save some memory compared to the sequential mode, but it is still a waste of memory than the precise offset.
For more information about the memory layout of the struct type in the. NET hosting environment, read the blog post "happyhippy:
Http://www.cnblogs.com/happyhippy/archive/2007/04/12/710927.aspx
Conclusion