Void のサンプル

このサンプルでは、引数として void ポインタを要求するアンマネージ関数にデータを渡す方法を示します。このサンプルでは 2 つの解決方法を示します。

Void のサンプルで使用するアンマネージ関数とその関数宣言を次に示します。

  • PinvokeLib.dll からエクスポートされる SetData

    void SetData(DataType typ, void* object)
    

PinvokeLib.dll はカスタム アンマネージ ライブラリであり、上記の関数に関する実装を含みます。

このサンプルでは、LibWrap クラスには型の列挙体と 2 つのマネージ プロトタイプ メソッド、SetData および SetData2 が含まれます。これらのメソッドは、次のアプローチによって void* を要求するアンマネージ関数にデータを渡します。

  • SetDataDataType 列挙体とオブジェクトを宣言します。MarshalAsAttribute 属性により UnmanagedType 列挙体が AsAny に設定されます。AsAny は実行時にオブジェクトの型を決定し、その型としてオブジェクトをマーシャリングします。

  • SetData2 はメソッドをオーバーロードして DataType 列挙体を宣言し、倍精度浮動小数点数型または文字列型を識別します。キーワード ref (Visual Basic では ByRef) により、倍精度浮動小数点数を参照渡しを行います。

App クラスはメソッドを呼び出して、列挙体の要素を初期化します。最初のアプローチでは、列挙体の各要素を指定します。次のアプローチでは、最長の値型および文字列だけを指定します。

次のコード例のソース コードは、.NET Framework「プラットフォーム呼び出しの技術サンプル」で提供されています。

プロトタイプの宣言

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

関数の呼び出し

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

参照

概念

各種のマーシャリングのサンプル
プラットフォーム呼び出しのデータ型
マネージ コードでのプロトタイプの作成