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
Types de données d'appel de plate-forme