我想从我的代码中调用第三方函数。该函数的原型是:
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);
答案 0 :(得分:1)
是的,这段代码没问题,除非你花一些时间编写辅助函数,否则考虑到ATL::CComVariant
的设计方式很难做得更好。关于这一点的几点想法。
将CComVariant
作为in VARIANT
传递是可以的 - 基本部分只是成员方式复制到函数参数中,并由被调用的函数从那里使用。没有深度复制发生,没关系,被调用者也可以使用该副本,如果它想要深度复制参数或AddRef()
它 - 它仍然可以这样做。
将CComVariant
的地址作为in VARIANT
传递是正常的(CComVariant*
隐式向上转换为VARIANT*
,该函数访问子对象),但不是世界上最好的代码。这就是原因。有很多类似的类拥有资源,其中最重要的是ATL::CComBSTR
,_bstr_t
,ATL::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;操作