COM使用ICollectionOnSTLImpl的枚举与集合中的引用计数
2011-06-10 23:00 ubunoon 阅读(359) 评论(0) 编辑 收藏 举报在ATL中实现COM接口的集合接口和枚举接口,相对比较简单,使用ICollectionOnSTLImpl基本上就可以完成,网络上相关的教程也很多。大致的代码
typedef std::vector<long> CollType;
typedef CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT>, CollType > EnumType;
typedef ICollectionOnSTLImpl<IDyVector, CollType, VARIANT, _Copy<VARIANT>, EnumType > CollectionType;
/////////////////////////////////////////////////////////////////////////////
// CDyVector
class ATL_NO_VTABLE CDyVector :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CDyVector, &CLSID_DyVector>,
public IEnumOnSTLImpl<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT>, CollType>,
public ...
上面的代码,对于只是使用long类型的数据,内部使用CollType的push方式添加数据,这个是毫无疑问是正确的。
但是当想使用VARIANT作为数据类型的时候,网络上大部分是直接给出
typedef std::vector<VARIANT> CollType;
方式的代码,如果没有碰到vt==VT_DISPATCH方式时,这个实现是没有问题的,但是当碰到VT_DISPATCH的时候,引用计数
就会出现不匹配,因为在push的时候,只是做了一个简单的operator=操作,这个操作,对于VARIANT仅仅只是简单的赋值,并不涉及引用计数问题
当使用外部变量赋值进来的时候,再次使用该变量,就有可能导致一次引用违例,之所以是有可能,是因为该变量可能在外部还被引用或者该变量虽然没有被引用,但是内存的gc还没有将其收取回来,此时访问时,不会出现问题,但是如同前面描述的,引用刚好被用尽的时候,gc将内存收回的时候,此时再次访问该数据,就会出现访问违例。
既然是一次operator=操作,那么使用CComVariant进行复制,就可以满足上面的操作,因为CComVariant进行了operator=重载,将operator=的操作修改为了CopyVariant的函数调用,该函数会在内部帮助我们判断,是需要直接复制还是需要进行引用计数+1的操作,此时CollType类型的变量,如果存在引用计数,就会保持一个引用计数+1的操作,使得内部的数据不会被gc回收,从而保证访问不出现违例。
*
* Copyright (c) 2011 Ubunoon.
* All rights reserved.
*
* email: netubu#gmail.com replace '#' to '@'
* http://www.cnblogs.com/ubunoon
* 欢迎来邮件定制各类验证码识别,条码识别,图像处理等软件
* 推荐不错的珍珠饰品,欢迎订购 * 宜臣珍珠(淡水好珍珠) */