mizera
asked on
Invoke call & [in,out] params
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(CLSI D_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({xx x-yyy-..}) ;
CComDispatchDriver pObj(pDisp);
for(...)
pObj->Invoke1(L"AddTime",& saTime);
, after this saTime is still empty. Why? What I do wrong?
Thanks a lot
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(CLSI
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({xx
CComDispatchDriver pObj(pDisp);
for(...)
pObj->Invoke1(L"AddTime",&
, after this saTime is still empty. Why? What I do wrong?
Thanks a lot
Check HRESULT of your call. It may show that call failed and why it happened
Ther is a chance that CComDispatchDriver::GetIDO fName() failed to match "AddTime" to dispid.
ASKER
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.
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.
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.
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.
ASKER
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::Invoke 2 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);
}
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::Invoke
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);
}
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
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",&
Your second parameter should be something
pObj->Invoke1(L"AddTime",&
So when you supply second parameter then COM would know that you want changed value back
ASKER
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?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.