tags:

views:

415

answers:

2

I have a COM object that I'm trying to use from C++ (not .NET), and all of the example programs and manual are written assuming the use of C#.NET or VB.NET. COM is new to me so I'm a bit overwhelmed. I'm using #import on the TLB but am struggling to deal with the variants that are used as parameters. I have one particular method, that according to the docs and the example programs in C#.NET, is supposed to return an object[]. Then I'm supposed to cast the first entry in this array to a ControlEvent which then tells me what to do with the rest of the objects in the array. The C#.NET example looks like:

object [] objEvent = (object []) Ctl.GetEvent();
ControlEvent ev = (ControlEvent) objEvent[0];

In my case, GetEvent is returning me a _variant_t and I need to know how to convert this to an object[] so that I can further process. Its not clear to me even how I express 'object' in C++. I see _variant_t documentation showing me a million things I can convert the variant to, but none of them seem to be converting to anything I can use. I'm hoping for some assistance converting the above C#.NET code to Visual C++

Thanks.

A: 

Typically, you look at the vt member of the variant to see what type of thing it actually is. In this case I would expect it to be an array, so you would expect that the vartype would be some variation on VT_ARRAY (usually it is bitwise OR'ed with the type of the members). Then, you get the parray member which contains the SAFEARRAY instance that actually holds the array, and use the normal safe array functions to get the data out of the array.

1800 INFORMATION
Thanks, I think you've set me on the right track. The vt is VT_ARRAY || VT_VARIANT, I get back from the API call a SafeArray w/ two elements, each of which is a VT_I4. However lVal for both is zero, so I'm still stuck on how I'm supposed to turn these VT_I4's into pointers to objects
bdk
Can you show the code that you've used to retrieve `SAFEARRAY` elements and got `VT_I4`?
Pavel Minaev
_variant_t v = m_pCtl->getNextEvent()printf ("Variant Type is %x\n", v.vt); [[Prints 0x200c]]_variant_t itemLONG idx=0HRESULT hr = SafeArrayGetElement(v.parray, [[prints 3]]
bdk
If the return values were pointers to objects, the type would be VT_DISPATCH or VT_UNKNOWN - since it is VT_I4, the method is returning some kind of integer value.
1800 INFORMATION
A: 

I haven't done this, but from reading the documentation for the _variant_t class (and the comments below which corrected my original post), I think you should read the vt field of the _variant_t instance (actually the VARTYPE vt field of the VARIANT instance: the _variant_t instance directly derives from VARIANT) to see what type of thing it contains, as described in the reference documentation for the VARIANT struct. One you know what type of thing is contained in the variant, use the corresponding type-specific operator to read it.

You'll be in for some hurt if you try to use COM without understanding it (and you may want a book which describes that); you may well need to know about the IUnknown interface and the AddRef method, for example.

ChrisW
You do not detach the VARIANT instance from the _variant_t wrapper, unless you need to pass it whole to some external interface. The _variant_t is a smart wrapper class that can be treated more or less as the underlying instance
1800 INFORMATION
How else (without detaching the VARIANT) do you read the VARIANT's vt field value? I don't see in the documentation a _variant_t method to return the VARTYPE.
ChrisW
You do instance.vt - the _variant_t instance directly derives from VARIANT
1800 INFORMATION