Click to Rate and Give Feedback

  Switch on low bandwidth view
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
.NET Framework Class Library
StructLayoutAttribute Class

The StructLayoutAttribute class allows the user to control the physical layout of the data fields of a class or structure.

Namespace:  System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)
Visual Basic (Declaration)
<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct, Inherited := False)> _
<ComVisibleAttribute(True)> _
Public NotInheritable Class StructLayoutAttribute _
    Inherits Attribute
Visual Basic (Usage)
Dim instance As StructLayoutAttribute
C#
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct, Inherited = false)]
[ComVisibleAttribute(true)]
public sealed class StructLayoutAttribute : Attribute
Visual C++
[AttributeUsageAttribute(AttributeTargets::Class|AttributeTargets::Struct, Inherited = false)]
[ComVisibleAttribute(true)]
public ref class StructLayoutAttribute sealed : public Attribute
JScript
public final class StructLayoutAttribute extends Attribute

You can apply this attribute to classes or structures.

Typically, the common language runtime controls the physical layout of the data fields of a class or structure in managed memory. If the class or structure needs to be arranged a certain way, you can use StructLayoutAttribute. Explicit control of a class layout is important if the class is to be passed to unmanaged code that expects a specific layout. The LayoutKind value Sequential is used to force the members to be laid out sequentially in the order they appear. Explicit controls the precise position of each data member. With Explicit, each member must use the FieldOffsetAttribute to indicate the position of that field within the type.

C#, Visual Basic. NET, and C++ compilers apply the Sequential layout value to structures by default. For classes, you must apply the Sequential value explicitly. The Type Library Importer (Tlbimp.exe) also applies this attribute; it always applies the Sequential value when it imports a type library.

The following example demonstrates a managed declaration of the GetSystemTime function and defines MySystemTime class with LayoutKind..::.Explicit layout. The GetSystemTime gets the system time and prints to the console.

Visual Basic
Imports System
Imports System.Runtime.InteropServices

Namespace InteropSample

   <StructLayout(LayoutKind.Explicit, Size:=16, CharSet:=CharSet.Ansi)> _
   Public Class MySystemTime
      <FieldOffset(0)> Public wYear As Short
      <FieldOffset(2)> Public wMonth As Short
      <FieldOffset(4)> Public wDayOfWeek As Short
      <FieldOffset(6)> Public wDay As Short
      <FieldOffset(8)> Public wHour As Short
      <FieldOffset(10)> Public wMinute As Short
      <FieldOffset(12)> Public wSecond As Short
      <FieldOffset(14)> Public wMilliseconds As Short
   End Class 'MySystemTime


   Class LibWrapper

      <DllImport("kernel32.dll")> _
      Public Shared Sub GetSystemTime(<MarshalAs(UnmanagedType.LPStruct)> ByVal st As MySystemTime)
      End Sub
   End Class 'LibWrapper

   Class TestApplication

      Public Shared Sub Main()
         Try
            Dim sysTime As New MySystemTime()
            LibWrapper.GetSystemTime(sysTime)
            Console.WriteLine("The System time is {0}/{1}/{2} {3}:{4}:{5}", sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond)
         Catch e As TypeLoadException
            Console.WriteLine(("TypeLoadException : " + e.Message.ToString()))
         Catch e As Exception
            Console.WriteLine(("Exception : " + e.Message.ToString()))
         End Try
      End Sub 'Main
   End Class 'TestApplication
End Namespace 'InteropSample 

C#
using System;
using System.Runtime.InteropServices;

namespace InteropSample
{   

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

   class LibWrapper
   {
      [DllImport("kernel32.dll")]
      public static extern void GetSystemTime([MarshalAs(UnmanagedType.LPStruct)]MySystemTime st);
   };

   class TestApplication
   {      
      public static void Main()
      {
         try
         {
            MySystemTime sysTime = new MySystemTime();
            LibWrapper.GetSystemTime(sysTime);
            Console.WriteLine("The System time is {0}/{1}/{2} {3}:{4}:{5}", sysTime.wDay,
               sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);            
         }         
         catch(TypeLoadException e)
         {
            Console.WriteLine("TypeLoadException : " + e.Message);
         }
         catch(Exception e)
         {
            Console.WriteLine("Exception : " + e.Message);
         }
      }
   }
}

Visual C++
using namespace System;
using namespace System::Runtime::InteropServices;


[StructLayout(LayoutKind::Explicit,Size=16,CharSet=CharSet::Ansi)]
value class MySystemTime
{
public:

   [FieldOffset(0)]
   short wYear;

   [FieldOffset(2)]
   short wMonth;

   [FieldOffset(4)]
   short wDayOfWeek;

   [FieldOffset(6)]
   short wDay;

   [FieldOffset(8)]
   short wHour;

   [FieldOffset(10)]
   short wMinute;

   [FieldOffset(12)]
   short wSecond;

   [FieldOffset(14)]
   short wMilliseconds;
};

ref class LibWrapper
{
public:

   [DllImport("kernel32.dll")]
   static void GetSystemTime( MySystemTime * st );
};

int main()
{
   try
   {
      MySystemTime sysTime;
      LibWrapper::GetSystemTime(  &sysTime );
      Console::WriteLine( "The System time is {0}/{1}/{2} {3}:{4}:{5}", sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond );
   }
   catch ( TypeLoadException^ e ) 
   {
      Console::WriteLine( "TypeLoadException : {0}", e->Message );
   }
   catch ( Exception^ e ) 
   {
      Console::WriteLine( "Exception : {0}", e->Message );
   }

}


System..::.Object
  System..::.Attribute
    System.Runtime.InteropServices..::.StructLayoutAttribute
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360, Zune

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0, 1.1, 1.0

.NET Compact Framework

Supported in: 3.5, 2.0, 1.0

XNA Framework

Supported in: 3.0, 2.0, 1.0
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Attribute ignored when default properties are present.      HWM   |   Edit   |   Show History

Following a recent bug submission to Microsoft, it has now emerged that any struct that contains default properties (those defined as simply {get;set;} ) will have its field ordering impacted. The ordering of fields when one or more of them has a default property definition will not be the same as the ordering of the fields when no default property defintions are present.

The bug submission has number: 3606458.

Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Page view tracker