Partager via


OSInfo, exemple

Mise à jour : novembre 2007

Cet exemple montre comment passer soit une classe mise en forme par valeur, soit une structure par référence comme paramètre vers une fonction non managée qui s'attend à une structure avec une mémoire tampon de caractères incorporée.

L'exemple OSInfo utilise la fonction non managée suivante, illustrée avec sa déclaration de fonction d'origine :

  • GetVersionEx exportée à partir de Kernel32.dll.

    // BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);
    

La structure d'origine passée vers la fonction contient les éléments suivants :

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

Dans cet exemple, la classe OSVersionInfo et la structure OSVersionInfo2 génèrent les mêmes résultats lorsqu'elles sont passées vers la fonction non managée. L'attribut MarshalAsAttribute affecte à l'énumération UnmanagedType la valeur ByValTStr, qui est utilisée pour identifier les tableaux de caractères de longueur fixe inline qui apparaissent au sein des structures non managées.

La classe LibWrap contient deux prototypes : GetVersionEx passe la classe comme paramètre et GetVersionEx2 passe une structure comme paramètre. En appliquant explicitement les attributs InAttribute et OutAttribute, l'exemple s'assure que OSVersionInfo est marshalé comme paramètre en entrée/sortie et que l'appelant peut voir les changements remarshalés. (Pour de meilleures performances, l'attribut directionnel par défaut pour une classe est In, ce qui empêche l'appelant de voir les changements remarshalés.)

La structure OSVersionInfo2, qui est normalement passée par valeur, est déclarée avec le mot clé ref (ByRef en Visual Basic) et elle est passée par référence. La méthode Marshal.SizeOf détermine la taille, en octets, de la structure non managée.

Le code source pour les exemples de code suivants est fourni par Appel de plate-forme, exemple de technologie du .NET Framework.

Déclaration de prototypes

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

Appel de fonctions

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

Voir aussi

Tâches

Appel de plate-forme, exemple de technologie

Concepts

Marshaling de chaînes

Types de données d'appel de plate-forme

Marshaling par défaut pour les chaînes

Création de prototypes dans du code managé