Void Sample
This sample demonstrates how to pass data to an unmanaged function that expects a void pointer as an argument. The sample provides two solutions. The Microsoft .NET Framework SDK includes the complete Visual Basic .NET and C# versions of this sample in Samples\Technologies\Interop\Platform-Invoke.
The Void sample uses the following unmanaged function, shown with its original function declaration:
SetData exported from PinvokeLib.dll.
void SetData(DataType typ, void* object)
PinvokeLib.dll is a custom unmanaged library that contains an implementation for the previously listed function.
In this sample, the LibWrap
class contains an enumeration of types and two managed prototype methods: SetData
and SetData2
. These methods represent the following approaches for passing data to an unmanaged function expecting a void*:
SetData
declares theDataType
enumeration and an object. The MarshalAsAttribute attribute sets the UnmanagedType enumeration to AsAny, which determines the type of an object at run time and marshals the object as that type.SetData2
overloads the method to declare theDataType
enumeration and to identify a double or string type. The ref (ByVal in Visual Basic) keyword passes the double by reference.
The App
class calls the methods and initializes the enumeration elements. The first approach specifies each enumeration element; the second approach specifies only the largest value type and the string.
Declaring Prototypes
Public Class LibWrap
Public Enum DataType
DT_I2 = 1
DT_I4
DT_R4
DT_R8
DT_STR
End Enum 'DataType
' 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 'LibWrap
[C#]
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 );
}
Calling Functions
Public Class App
Public Shared Sub Main()
Console.WriteLine( "Calling SetData using AsAny..." + _
ControlChars.CrLf )
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( ControlChars.CrLf + "Calling SetData _
using overloading..." )
Console.WriteLine( ControlChars.CrLf )
Dim d As Double = 12
LibWrap.SetData2( LibWrap.DataType.DT_R8, d )
LibWrap.SetData2( LibWrap.DataType.DT_STR, "abcd" )
End Sub 'Main
End Class 'App
[C#]
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" );
}
}
See Also
Miscellaneous Marshaling Samples | Platform Invoke Data Types | Creating Prototypes in Managed Code