English 中文(简体)
Copying between VARIANT and _variant_t
原标题:

I m fairly certain that I can safely do:

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

But what about the other way around:

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

I ve been seeing some REALLY weird behaviour in my app which I put down to COM-related threading issues. But then I got wondering if I was screwing up memory using variants wrongly. In funcB, the VARIANT V is part of a safe-array being prepared for a COM call. With my V=vt line, am I doing a shallow copy which will break things when the same variant gets deallocated twice?

I really like _variant_t and avoiding all the ::VariantXXX methods, is there a neat way to use _variant_t in funcB to automate the copying?

最佳回答

First of all, yes, by using the assignment operator the way you do in funcB() you invoke shallow copying only (you might want to look into oaidl.h to see the VARIANT definition - it has no user-defined assignment operator and therefore shallow copying is done by the compiler).

This gets you into undefined behaviour if the other variant you copied from is cleared before you access the shallow copy (for example, if the variant type was VT_UNKNOWN the object pointed to could simply be destroyed after setting the reference count to 0 by calling the IUnknown::Release()).

_variant_t will not help you much since it has no methods for copying to another object - see comutil.h for class definition - it only copies from another object to itself.

The easiest way would be to use VariantCopy(). Not sure if the safearray will be initialized when you deal with it. If it is initialized with each element having VT_EMPTY you can just call VariantCopy(). Otherwise first call VariantInit() on the destination to initialize the destination. Calling VariantCopy() for a destination containing random uninitialized data can lead to undefined behaviour.

问题回答

If the VARIANT contains an object or a BSTR you will run into trouble when you deallocate the safearray since safearray deallocation will free the resource which it doesn t own. So when either the _variant_t or the safearray is destroyed the other will have a reference to a deallocated object.

For example if the VARIANT contains a pointer to IUnknown you ll mess up the reference count by calling Release more times than AddRef, if it contains a BSTR you ll just copy the pointer and not allocate a new string for the new variable.

This is why you should use VariantCopy, if you want to avoid Variant* methods (for a reason I can t understand) this can be done with _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(); 
}




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签