Ejemplo Void

Actualización: noviembre 2007

En este ejemplo se muestra cómo pasar datos a una función no administrada que espera recibir un puntero void como argumento. En el ejemplo se ofrecen dos soluciones.

En el ejemplo Void se utiliza la siguiente función no administrada, que se muestra con su declaración de función original:

  • SetData exportada desde PinvokeLib.dll.

    void SetData(DataType typ, void* object)
    

PinvokeLib.dll es una biblioteca personalizada y no administrada que contiene una implementación de la función enumerada anteriormente.

En este ejemplo, la clase LibWrap contiene una enumeración de tipos y dos métodos de prototipo administrados: SetData y SetData2. Estos métodos representan los enfoques siguientes para pasar datos a una función no administrada que espera recibir void*:

  • SetData declara la enumeración DataType y un objeto. El atributo MarshalAsAttribute establece la enumeración UnmanagedType en AsAny, que determina el tipo de un objeto en tiempo de ejecución y calcula la referencia del objeto como dicho tipo.

  • SetData2 sobrecarga el método para declarar la enumeración DataType e identificar un tipo doble o de cadena. La palabra clave ref (ByRef en Visual Basic) pasa el tipo doble por referencia.

La clase App llama a los métodos e inicializa los elementos de la enumeración. En el primer enfoque, se especifica cada elemento de la enumeración mientras que en el segundo sólo se especifica el tipo de valor mayor y la cadena.

El código fuente de los ejemplos de código siguientes lo proporciona el Ejemplo de tecnología de invocación de plataformas de .NET Framework.

Declaración de prototipos

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

Llamadas a funciones

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

Vea también

Conceptos

Diversos ejemplos de cálculo de referencias

Tipos de datos de invocación de plataforma

Crear prototipos en código administrado