我相当确定我可以安全地这样做:
void funcA(VARIANT &V,_variant_t &vt)
{
vt = V;
}但是反过来呢:
void funcB(VARIANT &V,_variant_t &vt)
{
V = vt;
}我在我的应用程序中看到了一些非常奇怪的行为,我将其归因于COM相关的线程问题。但后来我开始怀疑,我是不是错误地使用了变量来搞乱内存。在funcB中,变体V是为COM调用准备的安全数组的一部分。使用我的V=vt代码行,我是不是在做一个浅拷贝,当同一个变量被释放两次时,这个拷贝就会中断?
我真的很喜欢_variant_t,并且避免了所有的::VariantXXX方法,有没有一种在funcB中使用_variant_t自动复制的好方法?
发布于 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()可能导致未定义的行为。
发布于 2009-11-26 21:00:58
如果VARIANT包含一个对象或BSTR,当你释放safearray时,你的将会遇到麻烦,因为safearray释放会释放不属于它的资源。因此,当_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();
}https://stackoverflow.com/questions/1791447
复制相似问题