Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#客户端中ATL COM对象的引用计数即使使用接口指针的FinalEleaseComObject也不会下降到零_C#_Visual Studio 2010_Atl - Fatal编程技术网

C#客户端中ATL COM对象的引用计数即使使用接口指针的FinalEleaseComObject也不会下降到零

C#客户端中ATL COM对象的引用计数即使使用接口指针的FinalEleaseComObject也不会下降到零,c#,visual-studio-2010,atl,C#,Visual Studio 2010,Atl,我开发了一个简单的atl COM对象并创建了connectionpoint。接口类型的comobject是sink函数中的参数。我已经在连接点中的火灾事件和atlcom.h InternalAddRef/InternalRelease中设置了断点。就在fire事件之前,引用的数量是1,但当它到达C#中的sink函数时,它增加到2,一旦进入C#delegate,它就变成3。当我为接口调用FinalEleaseComObject时,它从3减少到1,但没有减少到0,因此不会调用对象析构函数并创建泄漏。

我开发了一个简单的atl COM对象并创建了connectionpoint。接口类型的comobject是sink函数中的参数。我已经在连接点中的火灾事件和atlcom.h InternalAddRef/InternalRelease中设置了断点。就在fire事件之前,引用的数量是1,但当它到达C#中的sink函数时,它增加到2,一旦进入C#delegate,它就变成3。当我为接口调用FinalEleaseComObject时,它从3减少到1,但没有减少到0,因此不会调用对象析构函数并创建泄漏。请帮助我了解如何将ref计数设置为0并避免泄漏

ret = p_IHUSNVRLyrEvents->OnLivePacket(Packet);//RefCount=1;From the connection point


Ref Count = 1
>   atl100.dll!AtlInternalQueryInterface()  + 0x9f bytes    
>   HUSNVRLayer.dll!ATL::CComObjectRootEx<ATL::CComMultiThreadModel>::InternalAddRef()  Line 2622   C++
    HUSNVRLayer.dll!ATL::CComObject<CPacket>::AddRef()  Line 2870   C++
    atl100.dll!AtlInternalQueryInterface()  + 0x42 bytes    
    HUSNVRLayer.dll!ATL::CComObjectRootBase::InternalQueryInterface(void * pThis, const ATL::_ATL_INTMAP_ENTRY * pEntries, const _GUID & iid, void * * ppvObject)  Line 2453 + 0x18 bytes   C++
    HUSNVRLayer.dll!CPacket::_InternalQueryInterface(const _GUID & iid, void * * ppvObject)  Line 111 + 0x3a bytes  C++
    HUSNVRLayer.dll!ATL::CComObject<CPacket>::QueryInterface(const _GUID & iid, void * * ppvObject)  Line 2884  C++
Ref Count = 2

>   HUSNVRLayer.dll!ATL::CComObjectRootEx<ATL::CComMultiThreadModel>::InternalAddRef()  Line 2622   C++
    HUSNVRLayer.dll!ATL::CComObject<CPacket>::AddRef()  Line 2870   C++
Ref Count = 3
>   HUSNVRLayer.dll!ATL::CComMultiThreadModel::Decrement(long * p)  Line 359    C++
    HUSNVRLayer.dll!ATL::CComObjectRootEx<ATL::CComMultiThreadModel>::InternalRelease()  Line 2629 + 0x9 bytes  C++
    HUSNVRLayer.dll!ATL::CComObject<CPacket>::Release()  Line 2873 + 0xb bytes  C++
Ref Count = 2

When i reach the .Net Code and enter inside the refcount is 3
ret=p_ihunsvrylevents->OnLivePacket(Packet)//RefCount=1;从连接点
参考计数=1
>atl100.dll!AtlInternalQueryInterface()+0x9f字节
>HUSNVRLayer.dll!ATL::CCOMObjeToRoTeX::NealAldReFuffor(2622 C++)
HUSNVRLayer.dll!AtL::CCOMObj::AddReFor(2870 C++)
atl100.dll!AtlInternalQueryInterface()+0x42字节
HUSNVRLayer.dll!ATL::CCOMObjeCurtOutBase::IntualQueQue界面(Valu**PITS,const ATL::AtAtLyInPMAPITIONTRON*PANSITS,CONST.GUIDI&IID,Value*PPVObjt)行2453 +0x18字节C++
HUSNVRLayer.dll!CyBase::InIngalQueQue界面(const gui&iID,Value*ppvObjts)行111 +0x3a字节C++
HUSNVRLayer.dll!ATC::CCOMObjult::QueryInterface(const uGuID&IID,Value*ppvObjor)2884行C++
参考计数=2
>HUSNVRLayer.dll!ATL::CCOMObjeToRoTeX::NealAldReFuffor(2622 C++)
HUSNVRLayer.dll!AtL::CCOMObj::AddReFor(2870 C++)
参考计数=3
>HUSNVRLayer.dll!ATC::CCOMultTHEADEDMALL::减量(长*p)359 C++
HUSNVRLayer.dll!ATL::CCOMObjeTrtoToEX::内部释放()行2629 +0x9字节C++
HUSNVRLayer.dll!AcL::CCOMObjult::RelaseEo()行2873 +0xB字节C++
参考计数=2
当我到达.Net代码并在内部输入时,refcount是3

如果您看到FinalReleaseComObject的文档:通过将其引用计数设置为0,释放对运行时可调用包装(RCW)的所有引用。这并不保证基础com对象的释放。您能在InternalAddRef中看到堆栈跟踪吗?这可能会告诉您谁在引用您的com对象。根据文档,通过调用FinalEleaseComObject,引用计数应为零,但在调试atlcom.h时,引用计数仍为1,但FinalEleaseComObject返回zero@oguz我通过在FinalEleaseComObject上保持断点,并在命中该断点时在上放置断点来确认这一点内部释放。在进入内部版本时,我可以看到ref count为3,它一直递减到1,然后退出(理想情况下ref count应该一直减少到0..调用对象的析构函数是由COM控制的,但ref count应该为零,对吗?我的水晶球说IConnectionPoint;;Unadvise()未调用。换句话说,您忘记取消订阅事件处理程序。引用计数问题不应“修复”对于Marshal.FinalReleaseComObject,这只是隐藏了一个bug。这就是为什么我要检查InternalAddRef中的堆栈跟踪,而不是InternalRelease中的堆栈跟踪。或者两者都检查,并比较添加/释放堆栈跟踪。这可能会告诉您哪个添加堆栈跟踪没有释放COM对象