【问题标题】:Copying between VARIANT and _variant_t在 VARIANT 和 _variant_t 之间复制
【发布时间】:2010-12-19 23:19:48
【问题描述】:

我相当确定我可以安全地做到:

void funcA(VARIANT &V,_variant_t &vt)
{
    vt = V;
}

但是反过来呢:

void funcB(VARIANT &V,_variant_t &vt)
{
    V = vt;
}

我在我的应用程序中看到了一些非常奇怪的行为,我将其归结为与 COM 相关的线程问题。但后来我想知道我是否错误地使用变体搞砸了内存。在 funcB 中,VARIANT V 是为 COM 调用准备的安全数组的一部分。使用我的 V=vt 行,我是否在做一个浅拷贝,当同一个变体被释放两次时会破坏事情?

我真的很喜欢 _variant_t 并避免使用所有 ::VariantXXX 方法,有没有一种巧妙的方法可以在 funcB 中使用 _variant_t 来自动复制?

【问题讨论】:

    标签: c++ visual-c++ com ole variant


    【解决方案1】:

    首先,是的,通过在funcB() 中使用赋值运算符,您只调用浅拷贝(您可能想查看 oaidl.h 以查看 VARIANT 定义 - 它没有用户 -定义的赋值运算符,因此浅拷贝由编译器完成)。

    如果您复制的另一个变体在您访问浅拷贝之前被清除(例如,如果变体类型为VT_UNKNOWN,则指向的对象可以简单地在将引用计数设置为0 通过调用IUnknown::Release())。

    _variant_t 对您没有多大帮助,因为它没有复制到另一个对象的方法 - 请参阅 comutil.h 了解类定义 - 它只从另一个对象复制到自身。

    最简单的方法是使用VariantCopy()。不确定当您处理它时是否会初始化安全数组。如果它使用具有VT_EMPTY 的每个元素进行初始化,则只需调用VariantCopy()。否则首先在目的地上调用VariantInit() 来初始化目的地。为包含随机未初始化数据的目的地调用 VariantCopy() 可能会导致未定义的行为。

    【讨论】:

    • 当 safearray 和 _varaint_t被销毁了。
    • 在未初始化的 VARIANT 上调用 VariantClear 也会中断。在尝试复制到 VARIANT 之前,请确保使用 VariantInit 对其进行初始化。
    【解决方案2】:

    如果VARIANT 包含一个对象或BSTR,您在释放安全数组时遇到麻烦,因为安全数组释放将释放它不拥有的资源。因此,当 _variant_t 或 safearray 被销毁时,另一个将具有对已释放对象的引用。

    例如,如果VARIANT 包含指向IUnknown 的指针,您将通过调用Release 的次数超过AddRef 来弄乱引用计数,如果它包含BSTR,您只需复制指针,而不是为新变量分配新字符串。

    这就是为什么你应该使用VariantCopy,如果你想避免使用Variant* 方法(出于我无法理解的原因)这可以使用_variant_t::Detach() 来完成

    void funcB(VARIANT &V,_variant_t &vt)
    {
        _variant_t temp = vt;
        V = temp.Detach();
        // or in one line V = _variant_t(vt).Detach(); 
    }
    

    【讨论】:

      猜你喜欢
      • 2017-01-11
      • 2011-11-07
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2014-11-01
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多