加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

聚合接口过早释放导致“服务器出现意外情况”

发布时间:2020-05-24 12:02:38 所属栏目:程序设计 来源:互联网
导读:要说明这个问题,首先我说下聚合接口的使用,借助ATL我们是这么用的: /**/ ////////////////////////////////////////////////////////////////////////// // 例子 class CExample // :...... ... { BEGIN_COM_MAP(CExample) //...

要说明这个问题,首先我说下聚合接口的使用,借助ATL我们是这么用的:

/**/ //////////////////////////////////////////////////////////////////////////
// 例子

class CExample
// :......
... {
BEGIN_COM_MAP(CExample)
//......
//1.在接口映射表中加上要聚合出去的接口,并指定QI时
// 得到的接口指针
COM_INTERFACE_ENTRY_AGGREGATE(IID_IEXAMPLE,m_spUnk);
END_COM_MAP()

//......

DECLARE_GET_CONTROLLING_UNKNOWN()
DECLARE_PROTECT_FINAL_CONSTRUCT()

HRESULTFinalConstruct()
...{
HRESULThr=S_OK;
//2.我们一般是在FinalConstruct里面做聚合接口的创建
hr=CoCreateInstance(CLSID_EXAMPLE,
GetControllingUnknown(),
CLSCTX_ALL,
IID_IUnknown,
(void**)&m_spUnk);
returnhr;
}

HRESULTFinalRelease()
...{
//3.我们一般是在FinalRelease里面做聚合接口的释放
m_spUnk.Release();
}

public:
CComPtr<IUnknown>m_spUnk;
} ;

// 例子结束
/**/ //////////////////////////////////////////////////////////////////////////

2. 我的问题
我们如果都按上面的方法自然不会有错,但是如果我们不想在FinalConstruct中实现呢?
我的做法是和FinalConstruct/FinalRelease对应的写了两个函数Init()/Uninit(),但是使用
后却发现了莫名奇妙的"服务器出现意外情况",在注释掉部分代码后发现,是因为我在不正确
的地方释放了m_spUnk!我是在Uninit()里面进行的m_spUnk.Release();这样为什么会有问题?
问题就出在:接口映射表中有用到了这个m_spUnk,且这个不会加引用计数,如果你在Uninit中
就释放了这个m_spUnk那么在组件要退出时,他也会运行在接口映射表,这时就会出现异常,因
为他所调用的m_spUnk已经在之前Release了。

3.解决
知道问题了就好办了,我就干脆不把m_spUnkRelease放回FinalRelease,当然要判断一下是否为
空,看来写每一行代码都要对他的作用明明白白才可以。

Good luck~

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读