我想从我的代码中调用第3方函数。该函数的原型(prototype)是:

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);

最佳答案

是的,此代码是可以的,并且鉴于ATL::CComVariant的设计方式,很难做到更好,除非您花一些时间编写辅助函数。关于此的一些想法。

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

可以将CComVariant的地址作为in VARIANT传递(CComVariant*隐式转换为VARIANT*,该函数访问子对象),但不是世界上最好的代码。这就是为什么。有很多类似的类拥有资源,最重要的类是ATL::CComBSTR_bstr_tATL::CComPtr_com_ptr_t,并且它们都重载了operator&(),并且属于ATL命名空间的那些类只是将指针返回到存储的指针,而_bstr_t_com_ptr_t在返回指针之前释放拥有的对象。这就是为什么:

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

还有这个:
_com_ptr_t<IUnknown> ptr( initialize() );
&ptr;

有不同的效果。 ATL::CComVariant_variant_t都没有operator&()重载,这会使事情进一步复杂化。较干净的方法是使用“访问者提取器”方法,例如_variant_t::GetVARIANT(),但ATL::CComVariant没有这种方法。因此,使用&是您此处唯一的选择。

可以传递使用CComVariant作为&获得的out VARIANT*地址是可以的,但同样不是世界上最好的代码。当您确定变体为空但可以使用以下代码时,就可以了:
CComVariant var( obtainIUnknown() );
foo( whatever, whatever, &var );

将盲目地覆盖指针,并导致先前引用的对象泄漏。更好的方法是使用类似于_variant_t::GetAddress()的方法,该方法会清除变体,然后返回指向原始VARIANT的指针,但ATL::CComVariant同样没有这种方法。

因此,最底层的代码就是可以的,修改时要小心。如果您碰巧写了很多这样的代码,那么最好编写辅助函数来执行那些“提取”操作。

关于c++ - CComVariant作为变量通过,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36652902/

10-11 18:51