首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在VARIANT和_variant_t之间复制

在VARIANT和_variant_t之间复制
EN

Stack Overflow用户
提问于 2009-11-25 01:00:58
回答 2查看 6K关注 0票数 1

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

代码语言:javascript
复制
void funcA(VARIANT &V,_variant_t &vt)
{
    vt = V;
}

但是反过来呢:

代码语言:javascript
复制
void funcB(VARIANT &V,_variant_t &vt)
{
    V = vt;
}

我在我的应用程序中看到了一些非常奇怪的行为,我将其归因于COM相关的线程问题。但后来我开始怀疑,我是不是错误地使用了变量来搞乱内存。在funcB中,变体V是为COM调用准备的安全数组的一部分。使用我的V=vt代码行,我是不是在做一个浅拷贝,当同一个变量被释放两次时,这个拷贝就会中断?

我真的很喜欢_variant_t,并且避免了所有的::VariantXXX方法,有没有一种在funcB中使用_variant_t自动复制的好方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-11-25 14:43:22

首先,是的,通过使用赋值操作符,就像您在funcB()中所做的那样,您只能调用浅层复制(您可能希望查看oaidl.h来查看VARIANT定义-它没有用户定义的赋值操作符,因此浅层复制是由编译器完成的)。

如果您从中复制的另一个变量在您访问浅层副本之前被清除(例如,如果变量类型为VT_UNKNOWN,则通过调用IUnknown::Release()将引用计数设置为0后,指向的对象可能会被销毁),这会使您进入未定义的行为。

_variant_t帮不了你太多,因为它没有复制到另一个对象的方法--参见comutil.h的类定义--它只从另一个对象复制到它自己。

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

票数 3
EN

Stack Overflow用户

发布于 2009-11-26 21:00:58

如果VARIANT包含一个对象或BSTR,当你释放safearray时,你的将会遇到麻烦,因为safearray释放会释放不属于它的资源。因此,当_variant_t或safearray被销毁时,另一个将拥有对已释放对象的引用。

例如,如果VARIANT包含指向IUnknown的指针,则调用Release的次数会比调用AddRef的次数多,这会使引用计数变得混乱;如果包含BSTR,则只需复制指针,而不为新变量分配新的字符串。

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

代码语言:javascript
复制
void funcB(VARIANT &V,_variant_t &vt)
{
    _variant_t temp = vt;
    V = temp.Detach();
    // or in one line V = _variant_t(vt).Detach(); 
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1791447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档