向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们

最近做了一个C#调用C++dll的项目,由于对C#不太了解,出现的问题实在令我感到纠结,查找资料的时候发现了一些有用的信息,贴出来记录一下


转载自:http://zyd87818.blog.163.com/blog/static/17488150120138373747897/

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

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

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


示例代码:

转载自:http://www.cnblogs.com/joe62/archive/2009/12/18/1626900.html

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

 

        [DllImport("...")]
        public static extern bool HB_SDVR_SetParseCallBack(int lRealHandle, SrcDataParseCBHandler SrcDataParseCBFun, int nRseserved);

        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void SrcDataParseCBHandler(int nChl, System.IntPtr SrcDataBuf, int nSize, int nFrameType, VIDEO_TIME ets, int user);

        SrcDataParseCBHandler srcDataParseCBHandler ;
        public int Start()
        {
            ...

                srcDataParseCBHandler = OnSrcDataParseCBHandler;
                bool resb = HBSDK.HB_SDVR_SetParseCallBack(CookieID, srcDataParseCBHandler, CookieID);
    ...    

        }
 

  public void OnSrcDataParseCBHandler(int nChl, System.IntPtr SrcDataBuf, int nSize, int nFrameType,                                VIDEO_TIME ets, int user)
        {...}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值