Convert VARIANT to…?
-
03-07-2019 - |
Question
Note:
- Attempting to invoke a method of an interface, of which the return type is
_variant_t
Code:
_variant_t resultsDataString;
_bstr_t simObjectNames;
simObjectNames = SysAllocString (L"TEST example 3");
resultsDataString = pis8->GetSimObject (simObjectNames);
inline function illustrated below, contained in .tli FILE:
inline _variant_t IS8Simulation::GetSimObject ( _bstr_t Name ) {
VARIANT _result;
VariantInit(&_result);
HRESULT _hr = get_SimObject(Name, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _variant_t(_result, false);
}
Note:
resultsDataString
is ofstruct
tagVARIANT
:VARTYPE vt
is 9 (unsigned short)IDispatch
IDispatch interface pointer
Question
- How can I then convert or extract the value?
- Possible using VariantChangeType?
- Another way?
Edit:
Note:
Looking to transform the following, Visual Basic code to Visual C++
MFC or ATL, if need be
Ideally, pure C++
Visual basic equivalent:
Public example1, example2 As SIMUL8.S8SimObject
Dim numberOfexamples As Variant
Dim resultString As Variant
Set example1 = MySimul8.SimObject("Example 1")
Set example2 = MySimul8.SimObject("Example 2")
numberOfexamples = example1.CountContents + example2.CountContents
resultString = CStr(numberOfexamples) & "*"
Solution
It appears you are using C++ as a COM client by relying on the VC++ compiler's built-in COM support. To make coding the client "easier" you've used #import
to generate C++ wrapper classes that attempt to hide all the COM details from you - or at least make the COM details simpler. So you're not using the COM SDK directly, but are using a client-side framework (I think of it like a light-weight COM-only framework akin to ATL or MFC).
Your example code, however, seems to be mixing the direct low-level COM SDK (VARIANT
s, BSTR
, SysAllocString
) with the #import
COM framework (_variant_t
, _bstr_t
, XXXXPtr
). COM from C++ is complicated at first - so in a perfect world I would suggest getting to know the basics of COM before going too far forward.
However, if you just want something to work I would guess this is #import
-style-of-COM-clients version of the VB code you provided:
_variant_t example1Var;
_variant_t example1Var;
SIMUL8::S8SimObjectQIPtr example1; // I'm guessing at this type-name from the VB code
SIMUL8::S8SimObjectQIPtr example2;
example1Var = pis8->GetSimObject(_bstr_t(L"Example 1"));
example2Var = pis8->GetSimObject(_bstr_t(L"Example 2"));
if (example1Var.vt == VT_DISPATCH && example2Var.vt == VT_DISPATCH)
{
// **UPDATE** to try to spoon feed the QI ptr...
example1 = IDispatchPtr((IDispatch*)example1Var);
example2 = IDispatchPtr((IDispatch*)example2Var);
// Does this screw-up reference counting?
int numberOfexamples = example1->CountContents + example2->CountContents;
}
UPDATE:
Documentation on #import
This makes using COM from C++ much easier, but is yet one other thing to learn...
OTHER TIPS
Take a look at the MSDN docs for _variant_t
There is a ChangeType method as well as Extractors.
Edit: Once you have an IDispatch
pointer, you need to use QueryInterface
to get a specific object type with members and methods, or use IDispatch::Invoke
. You can look at the MSDN Docs for IDispatch
. Either way, you need to know about the object type that is being returned by the IS8Simulation::GetSimObject
call.
Edit #2: Based on your VB code update, you want to use the same kind of code for C++, i.e. use the S8SimObject
type in its C++ form (look in the generated .tlh file for _COM_SMARTPTR_TYPEDEF
). Then you can directly do the same thing with CountContents
. Otherwise, you would need to look up the CountContents
DISPID with IDispatch::GetIDsOfNames
and then call invoke.
You don't have to convert the _variant_t
. It contains an IDispatch
interface pointer, so you can get it out like this:
if (v.vt == VT_DISPATCH)
{
IDispatchPtr pDispatch = v.pdispVal;
// Do something with pDispatch.
// e.g. assign it to a strongly-typed interface pointer.
}
There is a concept of "value" for an object (DISPID_VALUE).
Here is a codeproject.com article on resolving VARIANTs that might help.