积极答复者
请问调用回调函数出现的XXX::Invoke错误 怎么解决?

问题
-
错误信息:
对“Toolbox!Toolbox.Module1+Scallback::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。
程序主要用于获取系统窗口状态如窗口创建,激活,销毁等...
调用API的回调函数的时候 经常出现上面这个错误. 请问应该怎么处理 回调函数 才不会出错?
以下是主要代码:Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Scallback) As Integer Public Delegate Function Scallback(ByVal hwnd As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal Param As Integer) As Integer lpPrevWndProc = SetWindowLong(FormHwnd, -4, AddressOf callback) '调用回调函数 Public Function callback(ByVal hwnd As Integer, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal Param As Integer) As Integer If (wParam = 1) Then debug .print ("窗口创建消息") End If Return CallWindowProcA(lpPrevWndProc, hwnd, uMsg, wParam, Param) End Function
答案
-
你好,
参考这个链接中的第四条:确保在回调函数完成其工作之前,垃圾回收器不会回收委托。 如果委托作为参数进行传递,或者所包含的委托作为结构中的字段进行传递,则该委托在调用期间不会被回收。
一个常用的方法是使用静态变量(Shared)的回调方法,而不是一个局部变量,以避免被回收的委托。在这个例子中,你可以在回调函数外面定义(使用托管代码)一个私有的委托来阻止委托被回收。
引用链接:http://social.msdn.microsoft.com/Forums/en-US/vbide/thread/b1c5d7f2-ccf5-4899-b345-461dda046535/
http://msdn.microsoft.com/zh-cn/library/system.gc.keepalive.aspx
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/66ea26a6-7c3d-4e96-9336-e3f148659f22/
希望这些信息可以帮助到你。
Best regards,
Shanks Zen
MSDN Community Support | Feedback to us
- 已标记为答案 duanfeng89 2012年8月15日 17:15
全部回复
-
你好,
参考这个链接中的第四条:确保在回调函数完成其工作之前,垃圾回收器不会回收委托。 如果委托作为参数进行传递,或者所包含的委托作为结构中的字段进行传递,则该委托在调用期间不会被回收。
一个常用的方法是使用静态变量(Shared)的回调方法,而不是一个局部变量,以避免被回收的委托。在这个例子中,你可以在回调函数外面定义(使用托管代码)一个私有的委托来阻止委托被回收。
引用链接:http://social.msdn.microsoft.com/Forums/en-US/vbide/thread/b1c5d7f2-ccf5-4899-b345-461dda046535/
http://msdn.microsoft.com/zh-cn/library/system.gc.keepalive.aspx
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/66ea26a6-7c3d-4e96-9336-e3f148659f22/
希望这些信息可以帮助到你。
Best regards,
Shanks Zen
MSDN Community Support | Feedback to us
- 已标记为答案 duanfeng89 2012年8月15日 17:15