在COM中,您偶尔会发现具有this等签名的函数:
HRESULT STDMETHODCALLTYPE GetColorContexts(
UINT cCount,
IWICColorContext **ppIColorContexts,
UINT *pcActualCount)
这给我带来的问题是ppIColorContexts
必须是IWICColorContext *
的{{3}}数组。我尝试引用Vector
ATL::CComPtr<IWICColorContext>
的第一个元素而没有运气,它不会触发()
运算符,因此会抱怨类型不匹配。
vector<ATL::CComPtr<IWICColorContext>>
由于类型不匹配而失败,CComPtr
重载operator &
会破坏STL容器。BOOST_SCOPE_EXIT_ALL
有效,但仍然意味着我手动管理COM对象的生命周期,这是我想要摆脱的。CComPtr
- 我不喜欢这个解决方案,因为它让我有一段执行时间,如果出现问题,资源可能无法释放。std::unique_ptr<IWICColorContext[]>
带有自定义删除器 - 我还没有完全探索这种可能性,但它会确保COM对象始终被释放。答案 0 :(得分:2)
我会通过将原始指针向量传递给函数,然后复制到CComPtr
的另一个向量来实现。
std::vector<IWICColorContext *> vec(5, NULL);
UINT nActualCount = 0;
GetColorContexts(vec.size(), &vec[0], &nActualCount);
std::vector<CComPtr<IWICColorContext> > results(vec.begin(), vec.begin() + nActualCount);
唯一不幸的是,CComPtr
构造函数执行AddRef
所以你必须在原始指针丢失之前对其进行相应的Release
。
for (auto it = vec.begin(); it != vec.end(); ++it)
if (*it != NULL)
(*it)->Release();
vec.clear();
答案 1 :(得分:1)
最终解决方案由igor tandetnik在上述评论中描述:
基本上在VC2010 + ATL::CComPtr
中有sizeof
与它们所代表的指针相同(例如sizeof(ATL::CComPtr<IWICColorContext>) == sizeof(IWICColorContext*)
),我最好能说明这是因为它们没有虚函数因此不需要vTable。然而,这是 高度危险 ,因为它依赖于编译器实现细节。因此,以下工作:
std::vector<ATL::CComPtr<IWICColorContext> > > vec(5);
// CComPtrs are created and initialized here
GetColorContexts(vec.size(), &vec[0].m_T, ...);
击> <击> 撞击>
Mark提出了一个非常好的观点,即上面的解决方案完全依赖于编译器实现,这是危险的。但是,仅在ATL::CComPtr
调用之后附加GetColorContexts
的解决方案也无法解决,因为它不会是异常安全的。
最终我的解决方案(今天早上测试)是暂时从vector<IWICColorContext*>
vector<CComPtr<IWICColorContext>>
创建vector
这个临时{{1}}不会增加引用计数并允许我维护异常安全。< / p>
答案 2 :(得分:-1)
我认为你需要这样的东西:
long lSize = 0;
ptr->GetColorContexts(cCount, NULL, &lSize);//return required amount of contexts
IWICColorContext** ppColorContexts = NULL;
ppColorContexts = new IWICColorContext*[lSize];
ptr->GetColorContexts(cCount, ppColorContexts, &lSize);
//use something to wrap received raw interfaces with CComPtr -
//for example use for loop to pass them to new container,
//which stores CComPtr<IWICColorContext>