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 the DataType 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 the DataType 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