How to read elements in a VARIANT
Hi,
I can not find out how to read what is in a VARIANT, which is the result of calling a method GetAllProperties. The doc of this method only specifies that a VARIANT is returned. It should contain some kind of strings. I tried this :
VARIANT names;
_variant_t v1;
VARTYPE vtype;
long ix;
...
x->GetAllProperties(&names);
if (V_ISARRAY(&names)) {
SafeArrayGetVartype(names.parray,&vtype);
// this returns 0x0800 in vtype, so I assume it is an array of _variant_t !!!
for (ix=0;ix<nprops;ix++) {
SafeArrayGetElement(names.parray,&ix,&v1);
_bstr_t s1(v1);
printf("name=%s\n",(char *)s1);
}
}
But this ends in an exception during the statement "_bstr_t s1(v1);"
What do I do wrong ???
Linde Ackermans
Re: How to read elements in a VARIANT
Maybe something like this, assuming it's a string..
Code:
_variant_t vNetname;
char sNetname[40];
WideCharToMultiByte(CP_ACP,
0,
vNetname.bstrVal,
-1,
sNetname,
sizeof(sNetname),
NULL,
NULL);
Re: How to read elements in a VARIANT
Quote:
Originally Posted by
LindeA
Hi,
I can not find out how to read what is in a VARIANT, which is the result of calling a method GetAllProperties. The doc of this method only specifies that a VARIANT is returned. It should contain some kind of strings. I tried this :
VARIANT names;
_variant_t v1;
VARTYPE vtype;
long ix;
...
x->GetAllProperties(&names);
if (V_ISARRAY(&names)) {
SafeArrayGetVartype(names.parray,&vtype);
// this returns 0x0800 in vtype, so I assume it is an array of _variant_t !!!
for (ix=0;ix<nprops;ix++) {
SafeArrayGetElement(names.parray,&ix,&v1);
_bstr_t s1(v1);
printf("name=%s\n",(char *)s1);
}
}
But this ends in an exception during the statement "_bstr_t s1(v1);"
What do I do wrong ???
Linde Ackermans
Please use code tags....
Try changing your printf() to this
Code:
printf("name=%s\n", (LPSTR)(_bstr_t) v1.bstrVal);
And delete this line
Also...check the return values on SafeArrayGetElement()
Re: How to read elements in a VARIANT
There are two issues with the code.
First, memory is being leaked through v1. SafeArrayGetElement() returns a copy of the BSTR and it's your responsibility to free it. You can either call v1.Clear() on each iteration or just use v1.GetAddress() which calls Clear() for you.
[NOTE: Stuff in red italics is incorrect!]
Second, operator char* on a _bstr_t does not give you a narrow (ascii) C-string. It's meant for byte-level access to the BSTR. You either treat it as a wide string or convert it as BobS0327 suggested.
Also keep in mind that if you do anything "wrong" with _variant_t or _bstr_t then a _com_error will be thrown. So you may want to wrap all the work with a try/catch.
Code:
for (ix = 0; ix < nprops; ++ix)
{
HRESULT hres = SafeArrayGetElement(V_ARRAY(names), &ix, v1.GetAddress());
if (FAILED(hres))
_com_issue_error(hres);
_bstr_t s1(v1);
//printf("name=%ls\n", (const wchar_t*)s1);
wcout << L"name = " << (const wchar_t*)s1 << endl;
}//for
>> (LPSTR)(_bstr_t)v1.bstrVal
Not good for reasons mentioned above.
>> And delete this line
That's fine if you know the returned variant will always be a BSTR. If it isn't, then the _bstr_t constructor will turn it into a string if it can (which is handy sometimes).
gg
Re: How to read elements in a VARIANT
Quote:
Originally Posted by
Codeplug
>> (LPSTR)(_bstr_t)v1.bstrVal
Not good for reasons mentioned above.
gg
This exact is used to assign the bstrVal to a CString in 400,000 records with 20 fields in each record (8,000,000 times) each day for the last year within a try/catch and has not error'd out once...so I'm guessing the above code is good.
Re: How to read elements in a VARIANT
My mistake.
I was confusing _bstr_t with another class. It does in fact convert it to a narrow string using WideCharToMultiByte() with CP_ACP.
gg
Re: How to read elements in a VARIANT
Quote:
Originally Posted by
Codeplug
My mistake.
I was confusing _bstr_t with another class. It does in fact convert it to a narrow string using WideCharToMultiByte() with CP_ACP.
gg
No problem...you will get much more respect from others here with this statement "My mistake" than you will with thousands of posts...
"To err is human; to forgive, divine." Alexander Pope