Void 示例
更新:2007 年 11 月
该示例说明如何将数据传递给预计将 void 指针作为参数的非托管函数。该示例提供了两种解决方案。
Void 示例使用以下非托管函数(这里同时显示其原始函数声明):
从 PinvokeLib.dll 导出的 SetData。
void SetData(DataType typ, void* object)
PinvokeLib.dll 是一个自定义非托管库,它包含前面列出的函数的实现。
在该示例中,LibWrap 类包含一个类型枚举和两种托管原型方法:SetData 和 SetData2。这两种方法表示以下用于将数据传递给需要 void* 的非托管函数的方法:
SetData 声明 DataType 枚举和一个对象。MarshalAsAttribute 属性将 UnmanagedType 枚举设置为 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" );
}
}