Condividi tramite


Esempio di Void

In questo esempio viene illustrato come passare i dati a una funzione non gestita per la quale è previsto un puntatore void come argomento. Vengono fornite due soluzioni.

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

  • SetData esportata da PinvokeLib.dll.

    void SetData(DataType typ, void* object)
    

PInvokeLib.dll è una libreria non gestita personalizzata contenente un'implementazione per la funzione elencata in precedenza.

In questo esempio la classe LibWrap contiene un'enumerazione di tipi e due metodi di prototipi gestiti: SetData e SetData2, i quali rappresentano le seguenti modalità di passaggio dei dati a una funzione non gestita per la quale è previsto void*:

  • SetData dichiara l'enumerazione DataType e un oggetto. L'enumerazione UnmanagedType viene impostata dall'attributo MarshalAsAttribute su AsAny, che determina il tipo di un oggetto in fase di esecuzione ed effettua il marshalling dell'oggetto come tale tipo.

  • SetData2 effettua l'overload del metodo per dichiarare l'enumerazione DataType e identificare un tipo double o string. Mediante la parola chiave ref (o ByRef in Visual Basic), il tipo double viene passato per riferimento.

Con la classe App vengono chiamati i metodi e inizializzati gli elementi di enumerazione. Con la prima modalità si specifica ciascun elemento di enumerazione, con la seconda si specifica solo il tipo di valore più grande e la stringa.

Dichiarazione dei prototipi

Public Class LibWrap
    Public Enum DataType
        DT_I2 = 1
        DT_I4
        DT_R4
        DT_R8
        DT_STR
    End Enum

    ' Uses AsAny when void* is expected.
    Declare Sub SetData Lib "..\LIB\PInvokeLib.dll" ( _
        ByVal t As DataType, _
        <MarshalAs(UnmanagedType.AsAny)> ByVal o As Object)

    ' Uses overloading when void* is expected.
    Overloads Declare Sub SetData2 Lib "..\LIB\PInvokeLib.dll" Alias _
        "SetData" (ByVal t As DataType, ByRef d As Double)

    Overloads Declare Sub SetData2 Lib "..\LIB\PInvokeLib.dll" Alias _
        "SetData" (ByVal t As DataType, ByVal s As String)
End Class
public class LibWrap
{
    public enum DataType
    {
        DT_I2 = 1,
        DT_I4,
        DT_R4,
        DT_R8,
        DT_STR
    }

    // Uses AsAny when void* is expected.
    [DllImport( "..\\LIB\\PInvokeLib.dll" )]
    public static extern void SetData(DataType t,
        [MarshalAs(UnmanagedType.AsAny)] object o);

    // Uses overloading when void* is expected.
    [DllImport("..\\LIB\\PInvokeLib.dll", EntryPoint="SetData")]
    public static extern void SetData2(DataType t, ref double i);

    [DllImport("..\\LIB\\PInvokeLib.dll", EntryPoint="SetData")]
    public static extern void SetData2(DataType t, string s);
}
public ref class LibWrap
{
public:
    enum class DataType
    {
        DT_I2 = 1,
        DT_I4,
        DT_R4,
        DT_R8,
        DT_STR
    };

    // Uses AsAny when void* is expected.
    [DllImport("..\\LIB\\PInvokeLib.dll")]
    static void SetData(DataType t,
        [MarshalAs(UnmanagedType::AsAny)] Object^ o);

    // Uses overloading when void* is expected.
    [DllImport("..\\LIB\\PInvokeLib.dll", EntryPoint="SetData")]
    static void SetData2( DataType t, double% i);

    [DllImport("..\\LIB\\PInvokeLib.dll", EntryPoint="SetData")]
    static void SetData2( DataType t, String^ s);
};

Chiamata delle funzioni

Public Class App
   Public Shared Sub Main()
        Console.WriteLine("Calling SetData using AsAny..." + vbNewLine)
        LibWrap.SetData(LibWrap.DataType.DT_I2, CShort(12))
        LibWrap.SetData(LibWrap.DataType.DT_I4, CLng(12))
        LibWrap.SetData(LibWrap.DataType.DT_R4, CSng(12))
        LibWrap.SetData(LibWrap.DataType.DT_R8, CDbl(12))
        LibWrap.SetData(LibWrap.DataType.DT_STR, "abcd")

        Console.WriteLine(vbNewLine + "Calling SetData using overloading...")
        Console.WriteLine(vbNewLine)
        Dim d As Double = 12
        LibWrap.SetData2(LibWrap.DataType.DT_R8, d)
        LibWrap.SetData2(LibWrap.DataType.DT_STR, "abcd")
    End Sub
End Class
public class App
{
    public static void Main()
    {
        Console.WriteLine("Calling SetData using AsAny... \n");
        LibWrap.SetData(LibWrap.DataType.DT_I2, (short)12);
        LibWrap.SetData(LibWrap.DataType.DT_I4, (long)12);
        LibWrap.SetData(LibWrap.DataType.DT_R4, (float)12);
        LibWrap.SetData(LibWrap.DataType.DT_R8, (double)12);
        LibWrap.SetData(LibWrap.DataType.DT_STR, "abcd");

        Console.WriteLine("\nCalling SetData using overloading... \n");
        double d = 12;
        LibWrap.SetData2(LibWrap.DataType.DT_R8, ref d);
        LibWrap.SetData2(LibWrap.DataType.DT_STR, "abcd");
    }
}
public class App
{
public:
    static void Main()
    {
        Console::WriteLine("Calling SetData using AsAny... \n");
        LibWrap::SetData(LibWrap::DataType::DT_I2, (short)12);
        LibWrap::SetData(LibWrap::DataType::DT_I4, (long)12);
        LibWrap::SetData(LibWrap::DataType::DT_R4, (float)12);
        LibWrap::SetData(LibWrap::DataType::DT_R8, (double)12);
        LibWrap::SetData(LibWrap::DataType::DT_STR, "abcd");

        Console::WriteLine("\nCalling SetData using overloading... \n");
        double d = 12;
        LibWrap::SetData2(LibWrap::DataType::DT_R8, d);
        LibWrap::SetData2(LibWrap::DataType::DT_STR, "abcd");
    }
};

Vedere anche

Concetti

Esempi vari di marshalling

Tipi di dati di platform invoke

Creazione di prototipi nel codice gestito