Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Invoke call & [in,out] params

Posted on 2000-02-29
8
Medium Priority
?
652 Views
Last Modified: 2013-11-20
For simplify I have ATL COM object 'MyTimer' with method AddTime([in,out] VARIANT* p_vVal).
 The method get current time and append it into safe array 'p_vVal' by simplify code:

COleSafeArray sa;
if (p_vVal->vt & VT_ARRAY)
{
      sa.Attach(p_vVal);
      sa.Redim(...+1);
      index = ..
}
else
{
      sa.CreateOneDim(...);
      index = ..
}
sa.PutElement(index,now);
*p_vVal = sa.Detach();


 On client side I try use two ways:

1) First - this OK
      
      COleSafeArray saTime;

      CComPtr<IMyTimer> pObj;
      pObj.CoCreateInstance(CLSID_MyTimer);

      for(i=0; i<10; i++)
            pObj->AddTime(saTime);

, after this saTime have 10 elements


 2) Seccond - I try create object as Dispatch by CLSID and call method 'AddTimer' by Invoke.

      COleSafeArray saTime;

      CComPtr<IDispatch> pDisp;
      pDisp.CoCreateInstance({xxx-yyy-..});

      CComDispatchDriver pObj(pDisp);

      for(...)
            pObj->Invoke1(L"AddTime",&saTime);

, after this saTime is still empty. Why? What I do wrong?

Thanks a lot  
0
Comment
Question by:mizera
  • 5
  • 3
8 Comments
 
LVL 8

Expert Comment

by:gelbert
ID: 2569411
Check HRESULT of your call. It may show that call failed and why it happened
0
 
LVL 8

Expert Comment

by:gelbert
ID: 2569418
Ther is a chance that CComDispatchDriver::GetIDOfName() failed to match "AddTime" to dispid.
0
 

Author Comment

by:mizera
ID: 2569495
HRESULT is ok, but p_vVal is empty.

 I put breakpoint into AddTime.
In call AddTime is always p_vVal so I create, putElement and on finish Detach into p_vVal. But in second step is again p_vVal is empty!!!

 If I try call Invoke (in another com)only for interface method with [in] params, all was ok.

  I don't know what different is in call [in] and [out] params in Invoke call.


 
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Expert Comment

by:gelbert
ID: 2569814
I can not see what is wrong with your code. But try to make sure that imediately after detach VARIANT from COleSafeArray it is not empty(by the way, what do you mean unsed "empty").
You can try to make AddTime() take 2 parameters: one "in" and othetr "out".
See how it is going to work.
In/Out - it is direction for COM standard marshaler what to marshal and in which direction.
0
 

Author Comment

by:mizera
ID: 2572185
I try add second parameter, so now the interface method is like this: HRESULT Test([in,out] VARIANT* p_vInOut, [out] VARIANT* p_vOut) and before I call Test I append two element into p_vInOut.

 This is the same behaviour. I watch both params on method Test. On beginning p_vInOut has two element after Detach has tree elements, that's ok. But after return the p_vInOut has only two elements.
 Second [out]  parameter which I create on Test is return as Variant(VT_EMPTY),
after Detach had one element.

 I lookup source code of CComDispatchDriver::Invoke2 and append comment // ??

HRESULT Invoke2(DISPID dispid, VARIANT* pvarParam1, VARIANT* pvarParam2, VARIANT* pvarRet = NULL)
{
  // ?? I think that code below create copy of params, so if I append or
  // ?? modify params on Test call => I modify only copy ?
  CComVariant varArgs[2] = { *pvarParam2, *pvarParam1 };

  DISPPARAMS dispparams = { &varArgs[0], NULL, 2, 0};
  return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
}

0
 
LVL 8

Expert Comment

by:gelbert
ID: 2573153
Yes you are right!
You are using Invoke command which takes only [in] parameter and defaults [out] to NULL which means COM does not marshal changed value back since it assumes that you do not want it

// Invoke a method by name with a single parameter
      HRESULT Invoke1(LPCOLESTR lpszName, VARIANT* pvarParam1, VARIANT* pvarRet = NULL)

pObj->Invoke1(L"AddTime",&saTime);

Your second parameter should be something
pObj->Invoke1(L"AddTime",&saTime, &saNewTime);
 So when you supply second parameter then COM would know that you want changed value back


0
 

Author Comment

by:mizera
ID: 2575869
This mean that by Invoke call, I can have any [in] params but only one [out,retval] parametr? None [in,out] parametr or many [out] params?
 
0
 
LVL 8

Accepted Solution

by:
gelbert earned 240 total points
ID: 2576747
If you are using IDispatch::Invoke() to make a call then "Yes". If you want to have multiple [out] or [in,out] parameters then you would have to create custom interface
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question