Questo articolo è stato tradotto automaticamente. Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

Esempio di OSInfo

In questo esempio viene dimostrato come passare una classe formattata per valore o una struttura per riferimento come parametro a una funzione non gestita per la quale è prevista una struttura con un buffer di caratteri incorporato.

Nell'esempio di OSInfo viene utilizzata la seguente funzione non gestita, illustrata con la dichiarazione di funzione originale:

  • GetVersionEx esportata da Kernel32.dll.

    // BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);
    

La struttura originale passata alla funzione contiene i seguenti elementi:

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

In questo esempio, la classe OSVersionInfo e la struttura OSVersionInfo2 producono gli stessi risultati quando vengono passate alla funzione non gestita. Il valore dell'enumerazione UnmanagedType viene impostato dall'attributo MarshalAsAttribute su ByValTStr, che consente di identificare la matrice di caratteri inline a lunghezza fissa presente nella struttura non gestita.

La classe LibWrap contiene due prototipi: GetVersionEx passa la classe come parametro e GetVersionEx2 passa una struttura come parametro. Mediante l'applicazione esplicita degli attributi InAttribute e OutAttribute, nell'esempio vengono garantiti il marshalling di OSVersionInfo come parametro in/out e la visualizzazione delle modifiche restituite con il marshalling da parte del chiamante. Per questioni di prestazioni, l'attributo direzionale predefinito per una classe è In, condizione che impedisce al chiamante di vedere le modifiche restituite con il marshalling.

La struttura OSVersionInfo2, che viene in genere passata per valore, è dichiarata con la parola chiave ref (ByRef in Visual Basic) e viene passata per riferimento. Il metodo Marshal.SizeOf consente di determinare la dimensione in byte della struttura non gestita.


[StructLayout(LayoutKind.Sequential)]
public class OSVersionInfo
{
    public int OSVersionInfoSize;
    public int MajorVersion;
    public int MinorVersion;
    public int BuildNumber;
    public int PlatformId;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
    public String CSDVersion;
}

[StructLayout(LayoutKind.Sequential)]
public struct OSVersionInfo2
{
    public int OSVersionInfoSize;
    public int MajorVersion;
    public int MinorVersion;
    public int BuildNumber;
    public int PlatformId;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
    public String CSDVersion;
}

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 static void Main()
    {
        Console.WriteLine("\nPassing OSVersionInfo as a class");

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

        LibWrap.GetVersionEx(osvi);

        Console.WriteLine("Class size:    {0}", osvi.OSVersionInfoSize);
        Console.WriteLine("OS Version:    {0}.{1}", osvi.MajorVersion, osvi.MinorVersion);

        Console.WriteLine("\nPassing OSVersionInfo as a struct" );

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

        LibWrap.GetVersionEx2(ref osvi2);
        Console.WriteLine("Struct size:   {0}", osvi2.OSVersionInfoSize);
        Console.WriteLine("OS Version:    {0}.{1}", osvi2.MajorVersion, osvi2.MinorVersion);
    }
}


Mostra: