Convert VARIANT to…?

北城以北 提交于 2019-12-06 07:45:05
Aardvark

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 (VARIANTs, 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...

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!