该示例说明如何将委托传递给需要函数指针的非托管函数。委托是可以容纳对方法的引用的类,并且等效于类型安全函数指针或回调函数。
说明: |
---|
当您在调用内部使用委托时,公共语言运行库将在该调用的持续时间内防止对委托执行垃圾回收。但是,如果非托管函数存储该委托以供在该调用完成后使用,则您必须手动防止进行垃圾回收,直到非托管函数完成对该委托的使用为止。有关更多信息,请参见 HandleRef 示例和 GCHandle 示例。 |
Callback 示例使用以下非托管函数(这里同时显示其原始函数声明):
-
从 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 方法的签名相同。
下面的代码示例的源代码由 .NET Framework 平台调用技术示例 提供。
声明原型
Visual Basic
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
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 ); }
调用函数
Visual Basic
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
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 ); … } }
请参见