CComVariant传递为VARIANT

时间:2016-04-15 16:59:21

标签: c++ com variant

我想从我的代码中调用第三方函数。该函数的原型是:

HRESULT foo(/*[in]*/VARIANT, /*[in]*/VARIANT*, /*[out]*/VARIANT*)

目前我在VARIANT变量周围使用CComVariant包装器,我想将它们传递给这个函数。我有点困惑,我应该怎么做。在输入参数的情况下,我应该直接传递它们,还是将它们分离成一个简单的VARIANT并传递这些变量?我可以看到,两个版本都有效,但哪个是更​​清洁和推荐的方法?我目前的代码是这样的:

CComVariant param0(CComBSTR( "Hello world"));
CComVariant param1(VARIANT_FALSE);
CComVariant param2;
HRESULT hr = foo(param0, &param1, &param2);

1 个答案:

答案 0 :(得分:1)

是的,这段代码没问题,除非你花一些时间编写辅助函数,否则考虑到ATL::CComVariant的设计方式很难做得更好。关于这一点的几点想法。

CComVariant作为in VARIANT传递是可以的 - 基本部分只是成员方式复制到函数参数中,并由被调用的函数从那里使用。没有深度复制发生,没关系,被调用者也可以使用该副本,如果它想要深度复制参数或AddRef()它 - 它仍然可以这样做。

CComVariant的地址作为in VARIANT传递是正常的(CComVariant*隐式向上转换为VARIANT*,该函数访问子对象),但不是世界上最好的代码。这就是原因。有很多类似的类拥有资源,其中最重要的是ATL::CComBSTR_bstr_tATL::CComPtr_com_ptr_t,所有这些类都有{{1}重载以及属于operator&()命名空间的那些只返回指向存储指针的指针,但ATL_bstr_t在返回指针之前释放拥有的对象。这就是为什么:

_com_ptr_t

和此:

ATL::CComPtr<IUnknown> ptr( initialize() );
&ptr;

有不同的效果。 _com_ptr_t<IUnknown> ptr( initialize() ); &ptr; ATL::CComVariant都没有_variant_t重载,这使事情变得更加复杂。更干净的方法是使用&#34;访问器提取器&#34;诸如operator&()_variant_t::GetVARIANT()之类的方法没有这样的方法。因此,使用ATL::CComVariant是您在这里唯一的选择。

将使用&获得的CComVariant地址作为&传递是可以的,但同样不是世界上最好的代码。当你确定变量是空的但是这段代码时,它很好:

out VARIANT*

将盲目地覆盖指针并导致先前引用的对象泄露。更好的方法是使用CComVariant var( obtainIUnknown() ); foo( whatever, whatever, &var ); 清除变量然后返回指向原始_variant_t::GetAddress()的指针,但VARIANT没有这样的方法。

所以最底层就是你的代码没问题,修改它时要小心。如果你碰巧写了很多像这样的代码,你可能最好写一些辅助函数来做那些&#34;提取&#34;操作