CComVariant 作为 VARIANT 传递

CComVariant passing as VARIANT

我想从我的代码中调用第 3 方函数。函数原型为:

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 传递是可以的 - 基础部分只是按成员方式复制到函数参数中,并由那里的被调用函数使用。没有深度复制发生,没关系,被调用者也可以使用副本,如果它想要深度复制参数或 AddRef() 它 - 它仍然可以这样做。

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

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

还有这个:

_com_ptr_t<IUnknown> ptr( initialize() );
&ptr;

有不同的效果。 ATL::CComVariant_variant_t 都没有 operator&() 超载,这使事情变得更加复杂。更简洁的方法是使用 "accessor extractor" 方法,例如 _variant_t::GetVARIANT()ATL::CComVariant 没有这样的方法。所以使用 & 是您在这里唯一的选择。

将使用 & 获得的 CComVariant 地址作为 out VARIANT* 传递是可以的,但同样不是世界上最好的代码。当您确定变体为空但此代码时很好:

CComVariant var( obtainIUnknown() );
foo( whatever, whatever, &var );

会盲目覆盖指针,导致之前引用的对象泄露。更好的方法是使用 _variant_t::GetAddress() 之类的方法来清除变体,然后 return 指向原始 VARIANT 的指针,但同样 ATL::CComVariant 没有这样的方法。

所以最下面的代码是可以的,修改的时候要小心。如果你碰巧写了很多这样的代码,你最好编写一些辅助函数来完成这些 "extraction" 操作。