StructLayoutAttribute 클래스
StructLayoutAttribute 클래스를 사용하면 클래스 또는 구조체의 데이터 필드에 대한 실제 레이아웃을 제어할 수 있습니다.
네임스페이스: System.Runtime.InteropServices
어셈블리: mscorlib(mscorlib.dll)
구문
‘선언
<ComVisibleAttribute(True)> _
<AttributeUsageAttribute(AttributeTargets.Class Or AttributeTargets.Struct, Inherited:=False)> _
Public NotInheritable Class StructLayoutAttribute
Inherits Attribute
‘사용 방법
Dim instance As StructLayoutAttribute
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct, Inherited=false)]
public sealed class StructLayoutAttribute : Attribute
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(AttributeTargets::Class|AttributeTargets::Struct, Inherited=false)]
public ref class StructLayoutAttribute sealed : public Attribute
/** @attribute ComVisibleAttribute(true) */
/** @attribute AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct, Inherited=false) */
public final class StructLayoutAttribute extends Attribute
ComVisibleAttribute(true)
AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct, Inherited=false)
public final class StructLayoutAttribute extends Attribute
설명
이 특성은 클래스 또는 구조에 적용될 수 있습니다.
일반적으로 공용 언어 런타임은 관리되는 메모리에 있는 클래스 또는 구조체의 데이터 필드에 대한 실제 레이아웃을 제어합니다. 클래스나 구조체를 특정 방식으로 정렬하려면 StructLayoutAttribute를 사용합니다. 특정 레이아웃이 필요한 비관리 코드에 클래스를 전달하려는 경우에는 클래스 레이아웃을 명시적으로 제어하는 것이 중요합니다. LayoutKind 값 Sequential은 나타나는 순서에 따라 멤버를 순차적으로 레이아웃할 때 사용되고 Explicit은 각 데이터 멤버의 위치를 정확하게 제어할 때 사용됩니다. 각 멤버는 Explicit와 함께 FieldOffsetAttribute를 사용하여 형식 내부에서 해당 필드의 위치를 나타내야 합니다.
C#, Visual Basic. NET 및 C++ 컴파일러는 기본적으로 구조체에 Sequential 레이아웃 값을 적용합니다. 클래스에는 사용자가 Sequential 값을 명시적으로 적용해야 합니다. 또한 형식 라이브러리 가져오기(Tlbimp.exe)는 형식 라이브러리를 가져올 때 Sequential 값을 적용합니다.
예제
다음 예제에서는 GetSystemTime
함수의 관리되는 선언을 보여 주고 LayoutKind.Explicit 레이아웃을 사용하여 MySystemTime
클래스를 정의합니다. GetSystemTime
은 시스템 시간을 가져와서 콘솔에 출력합니다.
<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)> 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
[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);
}
}
}
[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 );
}
}
/** @attribute StructLayout(LayoutKind.Explicit, Size = 16,
CharSet = CharSet.Ansi)
*/
public class MySystemTime
{
/** @attribute FieldOffset(0)
*/
public short wYear;
/** @attribute FieldOffset(2)
*/
public short wMonth;
/** @attribute FieldOffset(4)
*/
public short wDayOfWeek;
/** @attribute FieldOffset(6)
*/
public short wDay;
/** @attribute FieldOffset(8)
*/
public short wHour;
/** @attribute FieldOffset(10)
*/
public short wMinute;
/** @attribute FieldOffset(12)
*/
public short wSecond;
/** @attribute FieldOffset(14)
*/
public short wMilliseconds;
} //MySystemTime
class LibWrapper
{
/** @attribute DllImport("kernel32.dll")
*/
public static native void GetSystemTime(
/** @attribute MarshalAs(UnmanagedType.LPStruct)
*/
MySystemTime st);
} //LibWrapper
class TestApplication
{
public static void main(String[] args)
{
try {
MySystemTime sysTime = new MySystemTime();
LibWrapper.GetSystemTime(sysTime);
Console.WriteLine("The System time is {0}/{1}/{2} {3}:{4}:{5}",
new Object[] { (Int32)sysTime.wDay, (Int32)sysTime.wMonth,
(Int32)sysTime.wYear, (Int32)sysTime.wHour, (Int32)sysTime.
wMinute, (Int32)sysTime.wSecond });
}
catch (TypeLoadException e) {
Console.WriteLine("TypeLoadException : " + e.get_Message());
}
catch (System.Exception e) {
Console.WriteLine("Exception : " + e.get_Message());
}
} //main
} //TestApplication
상속 계층 구조
System.Object
System.Attribute
System.Runtime.InteropServices.StructLayoutAttribute
스레드로부터의 안전성
이 형식의 모든 public static(Visual Basic의 경우 Shared) 멤버는 스레드로부터 안전합니다. 인터페이스 멤버는 스레드로부터 안전하지 않습니다.
플랫폼
Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.
버전 정보
.NET Framework
2.0, 1.1, 1.0에서 지원
.NET Compact Framework
2.0, 1.0에서 지원
참고 항목
참조
StructLayoutAttribute 멤버
System.Runtime.InteropServices 네임스페이스