다음을 통해 공유


OSInfo 샘플

업데이트: 2007년 11월

이 샘플에서는 포함된 문자 버퍼가 있는 구조체를 필요로 하는 관리되지 않는 함수에 형식이 지정된 클래스를 값으로 전달하거나 구조체를 매개 변수를 통해 참조로 전달하는 방법을 보여 줍니다.

OSInfo 샘플에서는 다음의 관리되지 않는 함수를 사용합니다. 이 함수는 원래의 함수 선언과 함께 표시되어 있습니다.

  • Kernel32.dll에서 내보낸 GetVersionEx

    // BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);
    

이 함수에 전달된 원래 구조체에는 다음 요소가 포함되어 있습니다.

typedef struct _OSVERSIONINFO
{ 
  DWORD dwOSVersionInfoSize; 
  DWORD dwMajorVersion; 
  DWORD dwMinorVersion; 
  DWORD dwBuildNumber; 
  DWORD dwPlatformId; 
  TCHAR szCSDVersion[ 128 ]; 
} OSVERSIONINFO; 

이 샘플에서, OSVersionInfo 클래스 및 OSVersionInfo2 구조체는 관리되지 않는 함수에 전달될 때 동일한 결과를 생성합니다. MarshalAsAttribute 특성은 UnmanagedType 열거형 값을 ByValTStr로 설정합니다. ByValTStr은 관리되지 않는 구조체 내에 나타나는 고정 길이의 인라인 문자 배열을 식별하는 데 사용됩니다.

LibWrap 클래스에는 두 개의 프로토타입이 포함되어 있습니다. 이 중 GetVersionEx는 클래스를 매개 변수를 통해 전달하고 GetVersionEx2는 구조체를 매개 변수를 통해 전달합니다. 이 샘플에서는 OSVersionInfo가 In/Out 매개 변수로 마샬링되고 호출자가 다시 마샬링된 변경 내용을 볼 수 있도록 InAttributeOutAttribute 특성을 명시적으로 적용합니다. 성능상의 이유로 클래스에 대한 기본 방향 특성은 호출자가 다시 마샬링된 변경 내용을 볼 수 없도록 하는 In입니다.

일반적으로 값으로 전달되는 OSVersionInfo2 구조체는 ref(Visual Basi에서는 ByRef) 키워드를 사용하여 선언되고 참조로 전달됩니다. Marshal.SizeOf 메서드는 관리되지 않는 구조체의 크기를 바이트 단위로 확인합니다.

다음 코드 예제의 소스 코드는 .NET Framework Platform Invoke 기술 샘플을 통해 제공됩니다.

프로토타입 선언

< StructLayout( LayoutKind.Sequential )> _
Public Class OSVersionInfo

   Public OSVersionInfoSize As Integer
   …   
   < MarshalAs( UnmanagedType.ByValTStr, SizeConst := 128 )> _
   Public versionString As String
End Class 'OSVersionInfo

< StructLayout( LayoutKind.Sequential )> _
Public Structure OSVersionInfo2

   Public OSVersionInfoSize As Integer
   …
   < MarshalAs( UnmanagedType.ByValTStr, SizeConst := 128 )> _
   Public versionString As String
End Structure 'OSVersionInfo2

Public Class LibWrap
   Declare Ansi Function GetVersionEx Lib "kernel32" Alias _
   "GetVersionExA" ( <[In], Out> ByVal osvi As OSVersionInfo ) As Boolean
   
   Declare Ansi Function GetVersionEx2 Lib "kernel32" Alias _
"GetVersionExA" ( ByRef osvi As OSVersionInfo2 ) As Boolean
End Class 'LibWrap
[ StructLayout( LayoutKind.Sequential )]
public class OSVersionInfo 
{
    public int OSVersionInfoSize;
    …
   [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]    
    public String versionString;
}
[ StructLayout( LayoutKind.Sequential )]  
public struct OSVersionInfo2 
{
    public int OSVersionInfoSize;
    …
   [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
    public String versionString;
}
public class LibWrap 
{
   [ DllImport( "kernel32" )]
   public static extern bool GetVersionEx( [In, Out] OSVersionInfo osvi );

   [ DllImport( "kernel32", EntryPoint="GetVersionEx" )] 
   public static extern bool GetVersionEx2( ref OSVersionInfo2 osvi );  
}

함수 호출

Public Class App
   Public Shared Sub Main()
   
      Console.WriteLine( ControlChars.CrLf + "Passing OSVersionInfo _
         as class" )
      
      Dim osvi As New OSVersionInfo()
      osvi.OSVersionInfoSize = Marshal.SizeOf( osvi )
      
      LibWrap.GetVersionEx( osvi )
      Console.WriteLine( "Class size:    {0}", osvi.OSVersionInfoSize )
     … 
      Console.WriteLine( ControlChars.CrLf + "Passing OSVersionInfo _
         as struct" )
      
      Dim osvi2 As New OSVersionInfo2()
      osvi2.OSVersionInfoSize = Marshal.SizeOf( osvi2 )
      
      LibWrap.GetVersionEx2( osvi2 )
      Console.WriteLine( "Struct size:   {0}", osvi2.OSVersionInfoSize )
      …
   End Sub 'Main
End Class 'App
public class App
{
   public static void Main()
   {
      Console.WriteLine( "\nPassing OSVersionInfo as class" );

      OSVersionInfo osvi = new OSVersionInfo();
      osvi.OSVersionInfoSize = Marshal.SizeOf( osvi );

      LibWrap.GetVersionEx( osvi );
      
      Console.WriteLine( "Class size:    {0}", osvi.OSVersionInfoSize );
      …
      Console.WriteLine( "\nPassing OSVersionInfo as struct" );

      OSVersionInfo2 osvi2 = new OSVersionInfo2();
      osvi2.OSVersionInfoSize = Marshal.SizeOf( osvi2 );

      LibWrap.GetVersionEx2( ref osvi2 );
      Console.WriteLine( "Struct size:   {0}", osvi2.OSVersionInfoSize );
      …     
   }
}

참고 항목

작업

Platform Invoke 기술 샘플

개념

문자열 마샬링

플랫폼 호출 데이터 형식

문자열에 대한 기본 마샬링

관리 코드에서 프로토타입 만들기