LayoutKind 枚举

定义

当将对象导出到非托管代码时,控制该对象的布局。

public enum class LayoutKind
public enum LayoutKind
[System.Serializable]
public enum LayoutKind
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public enum LayoutKind
type LayoutKind = 
[<System.Serializable>]
type LayoutKind = 
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type LayoutKind = 
Public Enum LayoutKind
继承
LayoutKind
属性

字段

Auto 3

运行库自动为非托管内存中的对象的成员选择适当的布局。 使用此枚举成员定义的对象不能在托管代码的外部公开。 尝试这样做将引发异常。

Explicit 2

在未管理内存中的每一个对象成员的精确位置是被显式控制的,服从于 Pack 字段的设置。 每个成员必须使用 FieldOffsetAttribute 指示该字段在类型中的位置。

Sequential 0

对象的成员按照它们在被导出到非托管内存时出现的顺序依次布局。 这些成员根据在 Pack 中指定的封装进行布局,并且可以是不连续的。

示例

以下示例演示 函数的 PtInRect 托管声明,该函数检查点是否位于矩形内,并定义 Point 具有顺序布局的结构和 Rect 具有显式布局的结构。

enum class Bool
{
   False = 0,
   True
};


[StructLayout(LayoutKind::Sequential)]
value struct Point
{
public:
   int x;
   int y;
};


[StructLayout(LayoutKind::Explicit)]
value struct Rect
{
public:

   [FieldOffset(0)]
   int left;

   [FieldOffset(4)]
   int top;

   [FieldOffset(8)]
   int right;

   [FieldOffset(12)]
   int bottom;
};

ref class NativeMethods
{
public:

   [DllImport("user32.dll",CallingConvention=CallingConvention::StdCall)]
   static Bool PtInRect( Rect * r, Point p );
};

int main()
{
   try
   {
      Bool bPointInRect = (Bool)0;
      Rect myRect = Rect(  );
      myRect.left = 10;
      myRect.right = 100;
      myRect.top = 10;
      myRect.bottom = 100;
      Point myPoint = Point(  );
      myPoint.x = 50;
      myPoint.y = 50;
      bPointInRect = NativeMethods::PtInRect(  &myRect, myPoint );
      if ( bPointInRect == Bool::True )
            Console::WriteLine( "Point lies within the Rect" );
      else
            Console::WriteLine( "Point did not lie within the Rect" );
   }
   catch ( Exception^ e ) 
   {
      Console::WriteLine( "Exception : {0}", e->Message );
   }

}
enum Bool
{
   False = 0,
   True
};
[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;
}

internal static class NativeMethods
{
   [DllImport("user32.dll", CallingConvention=CallingConvention.StdCall)]
   internal static extern Bool PtInRect(ref Rect r, Point p);
};

class TestApplication
{
   public static void Main()
   {
      try
      {
         Bool bPointInRect = 0;
         Rect myRect = new Rect();
         myRect.left = 10;
         myRect.right = 100;
         myRect.top = 10;
         myRect.bottom = 100;
         Point myPoint = new Point();
         myPoint.x = 50;
         myPoint.y = 50;
         bPointInRect = NativeMethods.PtInRect(ref myRect, myPoint);
         if(bPointInRect == Bool.True)
            Console.WriteLine("Point lies within the Rect");
         else
            Console.WriteLine("Point did not lie within the Rect");
      }
      catch(Exception e)
      {
         Console.WriteLine("Exception : " + e.Message);
      }
   }
}
'  The program shows a managed declaration of the PtInRect function and defines Point
'  structure with sequential layout and Rect structure with explicit layout. The PtInRect
'  checks the point lies within the rectangle or not.
Imports System.Runtime.InteropServices

   Enum Bool
      [False] = 0
      [True]
   End Enum 
   <StructLayout(LayoutKind.Sequential)>  _
   Public Structure Point
      Public x As Integer
      Public y As Integer
   End Structure 
   
   <StructLayout(LayoutKind.Explicit)>  _   
   Public Structure Rect
      <FieldOffset(0)> Public left As Integer
      <FieldOffset(4)> Public top As Integer
      <FieldOffset(8)> Public right As Integer
      <FieldOffset(12)> Public bottom As Integer
   End Structure 
   
   
   Friend Class NativeMethods
      
      <DllImport("user32.dll", CallingConvention := CallingConvention.StdCall)>  _
      Friend Shared Function PtInRect(ByRef r As Rect, p As Point) As Bool
      End Function	
   End Class
   
   
   Class TestApplication
      
      Public Shared Sub Main()
         Try
            Dim bPointInRect As Bool = 0
            Dim myRect As New Rect()
            myRect.left = 10
            myRect.right = 100
            myRect.top = 10
            myRect.bottom = 100
            Dim myPoint As New Point()
            myPoint.x = 50
            myPoint.y = 50
            bPointInRect = NativeMethods.PtInRect(myRect, myPoint)
            If bPointInRect = Bool.True Then
               Console.WriteLine("Point lies within the Rect")
            Else
               Console.WriteLine("Point did not lie within the Rect")
            End If
         Catch e As Exception
            Console.WriteLine(("Exception : " + e.Message.ToString()))
         End Try
      End Sub 
   End Class

注解

此枚举与 一起使用 StructLayoutAttribute。 公共语言运行时默认使用 Auto 布局值。 为了减少与 Auto 值相关的布局相关问题,C#、Visual Basic 和 C++ 编译器为值类型指定 Sequential 布局。

重要

字段 StructLayoutAttribute.Pack 控制数据字段的对齐方式,因此无论指定的值如何 LayoutKind ,都会影响布局。 默认情况下,的 Pack 值为 0,表示当前平台的默认打包大小。 例如,使用 Explicit 布局值并在字节边界上指定字段对齐方式时,必须设置为 Pack 1 才能获得所需结果。

适用于