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