Fog Creek Software
Discussion Board




Where do OLE objects return VARIANT data?

I'm using MSXML in a C/C++ program, to parse a configuration file. Premise: at home I only have the standard edition Visual C++ compiler (you get it for free with the .NET SDK), that lacks the headers for native COM support, so no _variant_t

OK, so, I load the configuration file, get the root element, enumerate some child nodes, and finally I have to read some element's attributes. I get to the point of calling the attribute node's IXMLDOMNode::get_nodeValue() member... but I have no clue of where this method is supposed to return the data

I mean, the most logical way is passing a VT_BSTR variant, and then reading the data as a BSTR... but how will the method return the data? as a pointer to a buffer I should free (with CoTaskMemFree()?) when I don't need it anymore? as a pointer to an internal string I should copy in my own buffer? and what's exactly this string's lifetime? or I pass a buffer (as a BSTR? SAFEARRAY?) and the method fills it?

It's the first time I program with OLE and C/C++ at the same time - before, I used OLE from VB or scripts (where memory management is automatic) and C/C++ for fairly low-level programming (where there's always a clear indication of how to provide a buffer) - and the docs don't say anything about my dilemma, so I assume it's a very trivial thing

KJK::Hyperion
Monday, December 23, 2002

If you can use the CCom* classes (including CComBSTR) you can take a look at the following example:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmsrvsdk/htm/ixmldomnodeget_nodevalue.asp

However, to operate BSTRs in pure C++ you must do something like that:

LPCOLESTR pSrc;
pSrc = L"My string";

BSTR m_str;
m_str = ::SysAllocString(pSrc);

// Further use of m_str

Alexander Chalucov
Monday, December 23, 2002

To be completely correct, you should read the vt flag inside the variant and handle whatever it gives you. The whole point of a variant is that it can hold whatever type.

In practice, there's two solutions to the problem:

1) Assume it'll be (for example) VT_BSTR, write code to handle that, and return an E_INVALIDARG if it's not.

2) Again, write code for VT_BSTR, but before you process the variant call VariantChangeType to force it to your desired type. If the conversion fails, return E_INVALIDARG.

To free a variant, call VariantClear. That function has all the logic needed to free whatever a variant might be holding.

Chris Tavares
Monday, December 23, 2002

> To free a variant, call VariantClear. That function has all
> the logic needed to free whatever a variant might be
> holding.

thanks! VariantClear() is exactly what I needed. And I've discovered SysFreeString() too. Like I said, I'm just not used to this kind of programming. Who could imagine it was this easy? a single memory manager? automatic callee-side allocation of buffers? I mean, wow :-)

KJK::Hyperion
Monday, December 23, 2002

You may want to check out the CComBSTR wrapper class.  I've found it useful.

Alyosha`
Tuesday, December 24, 2002

*  Recent Topics

*  Fog Creek Home