Description





Description

The target objects for this attribute are classes and structures. By default, the physical layout of the data members of a target object is automatically arranged. When managed objects are passed as arguments to unmanaged code, the system creates their unmanaged representations. These unmanaged representations can be controlled with the StructLayoutAttribute. Such control is necessary if the unmanaged code expects a specific layout, packing size, or character set.

[Note: See the LayoutKind enumeration for a description of the possible layout schemes, and the FieldOffsetAttribute for further information on the layout of exported objects.]

Compilers are required to not preserve this type in metadata as a custom attribute. Instead, compilers are required to emit it directly in the file format, as described in Partition II of the CLI Specification. Metadata consumers, such as the Reflection API, are required to retrieve this data from the file format and return it as if it were a custom attribute.

Example

Figure

The following example demonstrates the use of the StructLayoutAttribute, and the FieldOffsetAttribute.

[Note: The non-standard PtInRect function used in this example indicates whether the specified point is located inside the specified rectangle. In this example, the layout setting on the Rect structure can be set to LayoutKind.Sequential with no bearing on the end result.]


using System;

using System.Runtime.InteropServices;



[StructLayout(LayoutKind.Sequential)]

public struct Point

{

    public int x;

    public int y;

}



[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;

}





class NativeCodeAPI

{

    [DllImport("User32.dll")]

    public static extern bool PtInRect(ref Rect r, Point p);

}



public class StructLayoutTest

{

    public static void Main()

    {

        Rect r;

        Point p1, p2;



        r.left = 0;

        r.right = 100;

        r.top = 0;

        r.bottom = 100;

 

        p1.x = 20;

        p1.y = 30;

 

        p2.x = 110;

        p2.y = 5;

        bool isInside1 = NativeCodeAPI.PtInRect(ref r, p1);

        bool isInside2 = NativeCodeAPI.PtInRect(ref r, p2);



        if(isInside1)

            Console.WriteLine("The first point is inside the rectangle.");

        else

            Console.WriteLine("The first point is outside the rectangle.");



        if(isInside2)

            Console.WriteLine("The second point is inside the rectangle.");

        else

            Console.WriteLine("The second point is outside the rectangle.");



    }

}


The output is

The first point is inside the rectangle.

The second point is outside the rectangle.


Figure


using System;

using System.Runtime.InteropServices;



/// <summary>

/// Sample demonstrating the use of the StructLayoutAttribute class.

/// Use this attribute to control the binary layout of types passed to

/// unmanaged code.

/// </summary>

internal class StructLayoutAttributeSample

{



    private static void Main()

    {

        GUITHREADINFO info = new GUITHREADINFO();



        info.cbSize = (uint)Marshal.SizeOf(typeof(GUITHREADINFO));

        

        // Get information about windows in the active thread, which will

        // typically be the console. Setting a breakpoint on this line will

        // mean the IDE contains the active thread.

        if (GetGUIThreadInfo(0, ref info))

        {

            Console.WriteLine("Window information for the foreground thread:");

            Console.WriteLine(

                "  Active window                           = 0x{0}",

                ((int)info.hwndActive).ToString("x8"));

            Console.WriteLine(

                "  Window that has keyboard focus          = 0x{0}",

                ((int)info.hwndFocus).ToString("x8"));

            Console.WriteLine(

                "  Window that has captured the mouse      = 0x{0}",

                ((int)info.hwndCapture).ToString("x8"));

            Console.WriteLine(

                "  Window displaying the caret             = 0x{0}",

                ((int)info.hwndCaret).ToString("x8"));

            Console.WriteLine(

                "  Caret dimensions (client coordinates)   = {0},{1} {2}x{3}",

                info.rcCaret.Left, info.rcCaret.Top,

                info.rcCaret.Right - info.rcCaret.Left,

                info.rcCaret.Bottom - info.rcCaret.Top);

        }

        else

        {

            Console.WriteLine("GetGUIThreadInfo failed.");

        }



        Console.WriteLine();

        Console.WriteLine();

        Console.WriteLine("Press Enter to continue");

        Console.ReadLine();

    }



    // The RECT type to use with GUITHREADINFO.

    [StructLayout(LayoutKind.Sequential)]

    private struct RECT

    {

        public int Left;

        public int Top;

        public int Right;

        public int Bottom;

    }



    // The GUITHREADINFO to use with GetGUIThreadInfo. Note that this type

    // contains an embedded RECT type.

    [StructLayout(LayoutKind.Sequential)]

    private struct GUITHREADINFO

    {

        public uint cbSize;

        public uint flags;

        public IntPtr hwndActive;

        public IntPtr hwndFocus;

        public IntPtr hwndCapture;

        public IntPtr hwndMenuOwner;

        public IntPtr hwndMoveSize;

        public IntPtr hwndCaret;

        public RECT rcCaret;

    }



    // Win32 method to retrieve information about windows in the specified

    // thread.

    [DllImport("user32.dll", SetLastError=true)]

    private static extern bool GetGUIThreadInfo(

        uint idThread, ref GUITHREADINFO lpgui);



}


The output is

Window information for the foreground thread:

  Active window                           = 0x001d07fe

  Window that has keyboard focus          = 0x001d07fe

  Window that has captured the mouse      = 0x00000000

  Window displaying the caret             = 0x00000000

  Caret dimensions (client coordinates)   = 0,0 0x0





Press Enter to continue



     Python   SQL   Java   php   Perl 
     game development   web development   internet   *nix   graphics   hardware 
     telecommunications   C++ 
     Flash   Active Directory   Windows