-
February 5th, 2009, 09:34 AM
#1
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
-
February 5th, 2009, 01:50 PM
#2
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);
-
February 5th, 2009, 02:29 PM
#3
Re: How to read elements in a VARIANT
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()
Last edited by Vanaj; February 5th, 2009 at 02:38 PM.
Jim
ATP BE400 CE500 (C550B-SPW) CE560XL MU300 CFI CFII
"The speed of non working code is irrelevant"... Of course that is just my opinion, I could be wrong.
"Nothing in the world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination are omnipotent. The slogan 'press on' has solved and always will solve the problems of the human race."...Calvin Coolidge 30th President of the USA.
-
February 5th, 2009, 03:02 PM
#4
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
Last edited by Codeplug; February 5th, 2009 at 03:56 PM.
Reason: Marked incorrect info
-
February 5th, 2009, 03:20 PM
#5
Re: How to read elements in a VARIANT
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.
Jim
ATP BE400 CE500 (C550B-SPW) CE560XL MU300 CFI CFII
"The speed of non working code is irrelevant"... Of course that is just my opinion, I could be wrong.
"Nothing in the world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination are omnipotent. The slogan 'press on' has solved and always will solve the problems of the human race."...Calvin Coolidge 30th President of the USA.
-
February 5th, 2009, 03:52 PM
#6
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
-
February 5th, 2009, 04:16 PM
#7
Re: How to read elements in a VARIANT
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
Jim
ATP BE400 CE500 (C550B-SPW) CE560XL MU300 CFI CFII
"The speed of non working code is irrelevant"... Of course that is just my opinion, I could be wrong.
"Nothing in the world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination are omnipotent. The slogan 'press on' has solved and always will solve the problems of the human race."...Calvin Coolidge 30th President of the USA.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|