回呼範例
更新:2007 年 11 月
這個範例示範如何將委派傳遞至預期函式指標的 Unmanaged 函式。委派是一種含有方法參考的類別,相當於型別安全函式指標或回呼函式 (Callback Function)。
注意事項: |
---|
當您在呼叫內使用委派時,在該呼叫期間,Common Language Runtime 會保護委派不被記憶體回收。不過,如果 Unmanaged 函式儲存在呼叫完成之後所要使用的委派,您必須在 Unmanaged 函式完成委派之前手動防止記憶體回收。如需詳細資訊,請參閱 HandleRef 範例 和 GCHandle 範例。 |
回呼範例使用下列 Unmanaged 函式,顯示其原始函式宣告:
從 PinvokeLib.dll 匯出 TestCallBack。
void TestCallBack(FPTR pf, int value);
從 PinvokeLib.dll 匯出 TestCallBack2。
void TestCallBack2(FPTR2 pf2, char* value);
PinvokeLib.dll 是自訂的 Unmanaged 程式庫,包含先前列示之函式的實作。
在這個範例中,LibWrap 類別包含 TestCallBack 和 TestCallBack2 方法的 Managed 原型。這兩個方法會將委派當成參數傳遞至回呼函式。委派的簽章 (Signature) 必須符合它所參考的方法簽章。例如,FPtr 和 FPtr2 委派具有相同於 DoSomething 與 DoSomething2 方法的簽章。
下列程式碼範例的原始程式碼是由 .NET Framework 平台叫用技術範例所提供。
宣告原型
Public 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
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 );
}
呼叫函式
Public 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
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 );
…
}
}