我想从我的代码中调用第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, ¶m1, ¶m2);
最佳答案
是的,此代码是可以的,并且鉴于ATL::CComVariant
的设计方式,很难做到更好,除非您花一些时间编写辅助函数。关于此的一些想法。
可以将CComVariant
传递为in VARIANT
没问题-基础部分只是按成员方式复制到function参数中,并从那里被调用的函数使用。没有深度复制发生,没关系,如果被调用者想深度复制参数或使用AddRef()
对其进行深度复制,它也可以使用该复制-仍然可以这样做。
可以将CComVariant
的地址作为in VARIANT
传递(CComVariant*
隐式转换为VARIANT*
,该函数访问子对象),但不是世界上最好的代码。这就是为什么。有很多类似的类拥有资源,最重要的类是ATL::CComBSTR
,_bstr_t
,ATL::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/