Compartilhar via


Amostra de OSInfo

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

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

  • GetVersionEx exportados do 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, o OSVersionInfo classe e o OSVersionInfo2 estrutura produzir os mesmos resultados quando passado para a função não gerenciada. O MarshalAsAttribute define o atributo de UnmanagedType o valor de enumeração para ByValTStr, que é usado para identificar o in-line, a matriz de caracteres de comprimento fixo que aparece dentro da estrutura não gerenciada.

O LibWrap classe contém dois protótipos: GetVersionExpassa a classe como um parâmetro e GetVersionEx2 passa uma estrutura como um parâmetro. Aplicando o InAttribute e OutAttribute atributos explicitamente, o exemplo garante que OSVersionInfo é empacotado como um parâmetro In/Out e o chamador podem ver as alterações empacotadas de volta. (Para desempenho, o padrão atributo direcional de uma classe é no, o que impede que o chamador vendo as alterações empacotado back.)

O OSVersionInfo2 estrutura, que normalmente é passada por valor, é declarada com a ref (ByRef em Visual Basic) palavra-chave e é passado por referência. O Marshal.SizeOf método determina o tamanho, em bytes, da estrutura não gerenciada.

A declaração de protótipos

<StructLayout(LayoutKind.Sequential)> _
Public Class OSVersionInfo
    Public OSVersionInfoSize As Integer
    Public MajorVersion As Integer
    Public MinorVersion As Integer
    Public BuildNumber As Integer
    Public PlatformId As Integer

    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> _
    Public CSDVersion As String
End Class

<StructLayout(LayoutKind.Sequential)> _
Public Structure OSVersionInfo2
    Public OSVersionInfoSize As Integer
    Public MajorVersion As Integer
    Public MinorVersion As Integer
    Public BuildNumber As Integer
    Public PlatformId As Integer

    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> _
    Public CSDVersion As String
End Structure

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
[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);
}
[StructLayout(LayoutKind::Sequential)]
public ref class OSVersionInfo
{
public:
    int OSVersionInfoSize;
    int MajorVersion;
    int MinorVersion;
    int BuildNumber;
    int PlatformId;

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst=128)]
    String^ CSDVersion;
};

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

    [MarshalAs(UnmanagedType::ByValTStr, SizeConst=128)]
    String^ CSDVersion;
};

public ref class LibWrap
{
public:
    [DllImport("kernel32")]
    static bool GetVersionEx([In, Out] OSVersionInfo^ osvi);

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

Chamando funções

Public Class App
    Public Shared Sub Main()
        Console.WriteLine(vbNewLine + "Passing OSVersionInfo as a class")

        Dim osvi As 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(vbNewLine + "Passing OSVersionInfo2 as a struct")

        Dim osvi2 As new OSVersionInfo2()
        osvi2.OSVersionInfoSize = Marshal.SizeOf(osvi2)

        LibWrap.GetVersionEx2(osvi2)
        Console.WriteLine("Struct size:   {0}", osvi2.OSVersionInfoSize)
        Console.WriteLine("OS Version:    {0}.{1}", osvi2.MajorVersion, osvi2.MinorVersion)
    End Sub
End Class
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);
    }
}
public ref class App
{
public:
    static void Main()
    {
        Console::WriteLine("\nPassing OSVersionInfo as a class");

        OSVersionInfo^ osvi = gcnew 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;
        osvi2.OSVersionInfoSize = Marshal::SizeOf(osvi2);

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

Consulte também

Conceitos

Empacotamento de Strings

Tipos de dados de invocação de plataforma

Padrão de empacotamento de Strings

Outros recursos

Creating Prototypes in Managed Code