A simple way to convert to/from VARIANT types in C++
Asked Answered
S

1

7

Are there any easy-to-use, high-level classes or libraries that let you interact with VARIANTs in Visual C++?

More specifically, I'd like to convert between POD types (e.g. double, long), strings (e.g. CString), and containers (e.g. std::vector) and VARIANTs. For example:

long val = 42;
VARIANT var;
if (ToVariant(val, var)) ...     // tries to convert long -> VARIANT
comObjPtr->someFunc(var);

std::vector<double> vec;
VARIANT var = comObjPtr->otherFunc();
if (FromVariant(var, vec)) ...   // tries VARIANT -> std::vector<double>

I (naively?) assumed that people working with COM do this all the time, so there would most likely be a single convenient library that handles all sorts of conversions. But all that I've been able to find is a motley assortment of wrapper classes that each convert a few types:

Is there any simple way -- short of switching to Visual Basic -- to avoid this nightmare of awkward memory management and bitwise VT_ARRAY | VT_I4 code?

Related questions:

Slap answered 1/3, 2010 at 21:4 Comment(2)
The question doesn't really apply to [c++] (which does not have that construct), just the visual dialect.Jed
For anyone who is curious what POD means here is a stack overflow answer. https://mcmap.net/q/17069/-what-are-pod-types-in-c-duplicateTrow
S
5

Well, most of the hard work is already done for you with the various wrapper classes. I prefer _variant_t and _bstr_t as they are more suited for conversion to/from POD types and strings. For simple arrays, all you really need is template conversion function. Something like the following:

// parameter validation and error checking omitted for clarity
template<typename T>
void FromVariant(VARIANT Var, std::vector<T>& Vec)
{
    CComSafeArray<T> SafeArray;
    SafeArray.Attach(Var.parray);
    ULONG Count = SafeArray.GetCount();
    Vec.resize(Count);
    for(ULONG Index = 0; Index < Count; Index++)
    {
        Vec[Index] = SafeArray[Index];
    }
}
....
std::vector<double> Vec;
VARIANT Var = ...;
FromVariant(Var, Vec);
...

Of course things get hairy (in regards to memory / lifetime management) if the array contains non-POD types, but it is still doable.

Succor answered 7/3, 2010 at 22:23 Comment(1)
Thanks -- that's useful, and pretty much what I've resigned myself to doing. Like you say, what's missing is non-POD support, and perhaps type checking/coercion (e.g. convert a variant of doubles to a vector of ints).Slap

© 2022 - 2024 — McMap. All rights reserved.