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