Callback Sample
This sample demonstrates how to pass delegates to an unmanaged function expecting function pointers. A delegate is a class that can hold a reference to a method and is equivalent to a type-safe function pointer or a callback function.
Note |
---|
When you use a delegate inside a call, the common language runtime protects the delegate from being garbage collected for the duration of that call. However, if the unmanaged function stores the delegate to use after the call completes, you must manually prevent garbage collection until the unmanaged function finishes with the delegate. For more information, see the HandleRef Sample and GCHandle Sample. |
The Callback sample uses the following unmanaged functions, shown with their original function declaration:
TestCallBack exported from PinvokeLib.dll.
void TestCallBack(FPTR pf, int value);
TestCallBack2 exported from PinvokeLib.dll.
void TestCallBack2(FPTR2 pf2, char* value);
PinvokeLib.dll is a custom unmanaged library that contains an implementation for the previously listed functions.
In this sample, the LibWrap
class contains managed prototypes for the TestCallBack
and TestCallBack2
methods. Both methods pass a delegate to a callback function as a parameter. The signature of the delegate must match the signature of the method it references. For example, the FPtr
and FPtr2
delegates have signatures that are identical to the DoSomething
and DoSomething2
methods.
The source code for the following code examples is provided by the .NET Framework Platform Invoke Technology Sample.
Declaring Prototypes
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 );
}
Calling Functions
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 );
…
}
}
See Also
Concepts
Miscellaneous Marshaling Samples
Platform Invoke Data Types
Creating Prototypes in Managed Code