回调示例
在本文中
此示例演示如何将委托传递给需要函数指针的非托管函数。委托是一个可以保存方法引用的类,相当于类型安全的函数指针或回调函数。Microsoft .NET Framework SDK 包含此示例的完整 Visual Basic .NET 和 C# 版本,位于 Samples\Technologies\Interop\Platform-Invoke 中。
注意 当您在调用中使用委托时,公共语言运行时会保护委托在该调用期间不被垃圾回收。但是,如果非托管函数存储委托以在调用完成后使用,则必须手动阻止垃圾回收,直到非托管函数完成委托。有关更多信息,请参阅HandleRef 示例和GCHandle 示例。
回调示例使用以下非托管函数,并显示其原始函数声明:
-
从 PinvokeLib.dll 导出的TestCallBack。
void TestCallBack(FPTR pf, int value);
-
从 PinvokeLib.dll 导出的TestCallBack2。
void TestCallBack2(FPTR2 pf2, char* value);
PinvokeLib.dll是一个自定义非托管库,其中包含前面列出的函数的实现。
在此示例中,该类包含和方法LibWrap
的托管原型。这两种方法都将委托作为参数传递给回调函数。委托的签名必须与其引用的方法的签名相匹配。例如,和委托具有与和方法相同的签名。TestCallBack
TestCallBack2
FPtr
FPtr2
DoSomething
DoSomething2
声明原型
VBPublic Delegate Function FPtr( ByVal value As Integer ) As Boolean
Public Delegate Function FPtr2( ByVal value As String ) As Boolean
Public Class LibWrap
' Declares managed prototypes for unmanaged functions.
Declare Sub TestCallBack Lib "..\LIB\PinvokeLib.dll" ( ByVal cb _
As FPtr, ByVal value As Integer )
Declare Sub TestCallBack2 Lib "..\LIB\PinvokeLib.dll" ( ByVal cb2 _
As FPtr2, ByVal value As String )
End Class 'LibWrap
[C#]
public delegate bool FPtr( int value );
public delegate bool FPtr2( String value );
public class LibWrap
{// Declares managed prototypes for unmanaged functions.
[ DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern void TestCallBack( FPtr cb, int value );
[ DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern void TestCallBack2( FPtr2 cb2, String value );
}
调用函数
VBPublic Class App
Public Shared Sub Main()
Dim cb As FPtr
cb = AddressOf App.DoSomething
Dim cb2 As FPtr2
cb2 = AddressOf App.DoSomething2
LibWrap.TestCallBack( cb, 99 )
LibWrap.TestCallBack2( cb2, "abc" )
End Sub 'Main
Public Shared Function DoSomething( ByVal value As Integer ) As Boolean
Console.WriteLine( ControlChars.CrLf + "Callback called with _
param: {0}", value )
...
End Function 'DoSomething
Public Shared Function DoSomething2( ByVal value As String ) As Boolean
Console.WriteLine( ControlChars.CrLf + "Callback called with _
param: {0}", value )
...
End Function 'DoSomething2
End Class 'App
[C#]
public class App
{
public static void Main()
{
FPtr cb = new FPtr( App.DoSomething );
LibWrap.TestCallBack( cb, 99 );
FPtr2 cb2 = new FPtr2( App.DoSomething2 );
LibWrap.TestCallBack2( cb2, "abc" );
}
public static bool DoSomething( int value )
{
Console.WriteLine( "\nCallback called with param: {0}", value );
...
}
public static bool DoSomething2( String value )
{
Console.WriteLine( "\nCallback called with param: {0}", value );
...
}
}