Solved

Invoke call & [in,out] params

Posted on 2000-02-29
8
642 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
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!

 
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 80 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

Suggested Solutions

Title # Comments Views Activity
Process filename extension 3 218
windows 10 how make picture as desktop background 2 73
dog bark java program 15 132
either24  challenge 19 110
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

738 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