您的位置:首页 > 编程语言 > C#

C#处理C++库回调报错_非托管代码传递委托被垃圾回收

2013-01-17 14:41 591 查看
如果非托管代码需要多次调用托管代码中的委托,请将委托保存为成员变量。

如果非托管代码需要多次调用托管代码中的回调,请将委托的引用保存为成员变量。否则会出现类似下面的异常:

检测到 CallbackOnCollectedDelegate

Message: 对“Demo!SomeNamespace.SomeClass+SomeDelegate::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。

如果不用成员变量,而用局部变量引用被new出来的委托,那么非托管代码可能刚开始的几次回调是OK的,但是接下来就会出现上面所说的异常,原因就在于GC将局部变量和局部变量引用的委托对象都销毁了,非托管代码再去访问那个函数指针时发现指针指向的地址已经无效。



解决例子

private LowLevelMouseProc _proc; 
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam); 
private IntPtr SetHook(LowLevelMouseProc proc) 
       { 
           using (Process curProcess = Process.GetCurrentProcess()) 
           using (ProcessModule curModule = curProcess.MainModule) 
           {

                _proc=HookCallback; 
                return SetWindowsHookEx(WH_MOUSE_LL, proc, 
                   GetModuleHandle(curModule.ModuleName), 0); 
           } 
       }




Reference:
对“XXX::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。

C#处理C++库回调报错_非托管代码传递委托被垃圾回收
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐