Compartilhar via


Exemplo de OSInfo

Este exemplo demonstra sistema autônomo passar uma classe formatada por valor ou uma estrutura por referência sistema autônomo um parâmetro para uma função não gerenciada que espera uma estrutura com um buffer de caractere incorporado.

O exemplo OSInfo utiliza a seguinte função não gerenciada, mostrada com sua declaração de função original:

  • GetVersionEx exportados de Kernel32.dll.

    // BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);
    

A estrutura original passada para a função contém os seguintes elementos:

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

Neste exemplo, a OSVersionInfo classe e o OSVersionInfo2 estrutura produzem os mesmos resultados quando transmitido para a função não gerenciada. The MarshalAsAttribute Define o atributo de UnmanagedType valor de enumeração para ByValTStr, que é usado para identificar o in-line, a matriz de caractere de comprimento fixo que aparece dentro da estrutura não gerenciada.

The LibWrap classe contém dois protótipos: GetVersionEx passa a classe sistema autônomo um parâmetro e GetVersionEx2 passa uma estrutura sistema autônomo um parâmetro. Aplicando o InAttribute e OutAttribute atributos explicitamente, o exemplo garante que OSVersionInfo é empacotado sistema autônomo um parâmetro de entrada/saída e o chamador podem ver sistema autônomo alterações novamente empacotadas. (Para desempenho, o padrão de atributo direcional para uma classe é, que impede que o chamador vendo as alterações empacotadas novamente.)

The OSVersionInfo2 estrutura, que normalmente é passada por valor, é declarada com o ref (ByRefpalavra-chave no Visual Basic) e é passada por referência.The Marshal.SizeOf método determina o dimensionar, em bytes, da estrutura não gerenciada.

O código-fonte para os exemplos de código a seguir é fornecido pelo.NET estrutura Invocação de plataforma Tecnologia Exemplo.

Declaração de protótipos

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

Chamando funções

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 );
      …     
   }
}

Consulte também

Tarefas

Invocação de plataforma Tecnologia Exemplo

Conceitos

marshaling de strings

Tipos de dados de invocação de plataforma

Padrão de marshaling de strings

Criando protótipos em código gerenciado