ADO Recordsets as DISPPARAMS in C++?

I have an MTS component authored in VB (it's a remote server), and I'd like to call methods on it from C++ (ATL). I can get an IUnknown pointer from CoCreateInstance, then an IDispatch pointer from CComQIPtr, then I can get the dispId of a method from pDisp->GetIDsOfNames (dispId comes back as 0x60030003), but I don't know how to set up the DISPPARAMS to call Invoke correctly.

The signature of the method is:
GetSessionID( [out] _Recordset** ppSessionRS, [out] _Recordset** ppErrorRS) in IDL style, or

GetSessionID( Recordset SessionRS, Recordset ppErrorRS) in VB style.

So I'm setting up my DISPPARAMS like this:

DISPPARAMS dispParams;
dispParams.rgvarg = vtArgs;
dispParams.rgvarg[0] = VT_DISPATCH; // do I need | VT_BYREF?
dispParams.rgvarg[1] = VT_DISPATCH;
dispParams.cArgs = 2;
dispParams.cArgs = 0; // 2?

hr = pDisp->Invoke( dispID // 0x6003003, a reasonable value?
                    NULL );

I get back 0xc0000005 (Access Violation) in hr. How do I set up dispParams correctly?

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

0x60030003 is an odd value for a dispid.  What HRESULT is GetIDsOfNames returning?  If it's not S_OK, then you cannot use the dispid returned.

The most common mistake I've seen with GetIDsOfNames is not converting the name you want to find to a proper OLE string.
barrettAuthor Commented:
GetIDsOfNames is returning S_OK, although I though that dispId looked weird as well. Here's my declaration for the name:

OLECHAR* szName = L"GetSessionID";

The example I was using wanted it to look like:

OLECHAR* szName = _T( "GetSessionID" );

but that wouldn't compile...
I'd have to conclude that if GetIDsOfNames is returning S_OK, that it's the right dispid.  Have you looked at the object in the OLE Viewer and check the dispids?
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

> do I need | VT_BYREF?

Yes, you have to.
Since it is an out pointer to pointer.
So you have to pass reference.

> dispParams.cArgs = 2;

It should be 2.

> I get back 0xc0000005 (Access >Violation) in hr. How do I set up >dispParams correctly?

The following problems can happen.

You should Initialize the variant to
VT_EMPTY for being safe side though
it is not an input parameter.

You are getting access violation
as you are not using the

barrettAuthor Commented:
Unfortunately, I still get the same behavior when I use VT_DISPATCH | VT_BYREF.

In answer to jhance's question, when I look at the object in the OLE/COM Viewer, the dispId is, in fact, 0x60030003, so that much is working correctly.

I just discovered the solution, however. I've declared two Recordset objects:

_RecordsetPtr pSessionRS(__uuidof(Recordset) );

_RecordsetPtr pErrorsRS(__uuidof(Recordset) );

In addition to setting the variant type to VT_DISPATCH|VT_BYREF, I need to set the ppdispVal value, like so:

vtArgs[0].ppdispVal = (IDispatch**)&pSessionRS;
vtArgs[1].ppdispVal = (IDispatch**)&pErrorsRS;

Now the Invoke call succeeds. Seems rather obvious now...

Thanks for the help, everybody!
What about points.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.