该示例说明如何将委托传递给需要函数指针的非托管函数。 委托是可以容纳对方法的引用的类,并且等效于类型安全函数指针或回调函数。
注意 |
|---|
当您在调用内部使用委托时,公共语言运行时将在该调用的持续时间内防止对委托执行垃圾回收。但是,如果非托管函数存储该委托以供在该调用完成后使用,则您必须手动防止进行垃圾回收,直到非托管函数完成对该委托的使用为止。有关更多信息,请参见 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 方法的签名相同。
声明原型
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
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 delegate bool FPtr(int value);
public delegate bool FPtr2(String^ value);
public ref class LibWrap
{
public:
// Declares managed prototypes for unmanaged functions.
[DllImport("..\\LIB\\PinvokeLib.dll")]
static void TestCallBack(FPtr^ cb, int value);
[DllImport("..\\LIB\\PinvokeLib.dll")]
static 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 )
' ...
Return True
End Function
Public Shared Function DoSomething2( ByVal value As String[]) As Boolean
Console.WriteLine( ControlChars.CrLf + "Callback called with param: {0}", value )
' ...
Return True
End Function
End Class
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);
// ...
return true;
}
public static bool DoSomething2( String value )
{
Console.WriteLine("\nCallback called with param: {0}", value);
// ...
return true;
}
}
public ref class App
{
public:
static void Main()
{
FPtr^ cb = gcnew FPtr(&App::DoSomething);
LibWrap::TestCallBack(cb, 99);
FPtr2^ cb2 = gcnew FPtr2(&App::DoSomething2);
LibWrap::TestCallBack2(cb2, "abc");
}
static bool DoSomething(int value)
{
Console::WriteLine("\nCallback called with param: {0}", value);
// ...
return true;
}
static bool DoSomething2(String^ value)
{
Console::WriteLine("\nCallback called with param: {0}", value);
// ...
return true;
}
};
注意