FIX: _AfxDispatchPushArgs Incorrectly AddRef's Invoke ArgumentLast reviewed: September 18, 1997Article ID: Q123274 |
1.50
WINDOWS
kbole kbbuglist kbfixlist
The information in this article applies to:
SYMPTOMSThe CCmdTarget::InvokeHelper member function uses an internal helper function _AfxDispatchPushArgs to set up the arguments to be passed eventually to IDispatch::Invoke on the OLE Automation object. If OLE objects are passed as arguments by value, the user may see memory leaks due to these objects not being freed after being passed to _AfxDispatchPushArgs.
CAUSEWhen _AfxDispatchPushArgs trys to change parameters passed by reference into the appropriate type, an extra AddRef is performed on the object by the VariantChangeType API. Consequently those objects do not shutdown correctly.
STATUSMicrosoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This bug was corrected in Microsoft Visual C++ 1.51 for Windows.
MORE INFORMATIONBelow is the original section followed by the fixed version of _AfxDispatchPushArgs responsible for changing the parameter data (OLEDISP1.CPP 546-559). === ORIGINAL VERSION === if (vt != VT_VARIANT && vt != pArg->vt) { VariantInit(&va); // argument is not of appropriate type, attempt to coerce it // // BUG: the VariantChangeType actually does an AddRef if pArg // is an LPDISPATCH or LPUNKNOWN parameter // if (VariantChangeType(&va, pArg, 0, vt) != NOERROR) { // argument could not be coerced *puArgErr = iArg; return DISP_E_TYPEMISMATCH; } ASSERT(va.vt == vt); pArg = &va;} === FIXED VERSION === NOTE: rgTempVars in the following code is a list of temporary VARIANT objects supplied, and explicitly cleaned up, by CCmdTarget::InvokeHelper to be used for the VariantChangeType API. if (vt != VT_VARIANT && vt != pArg->vt) { // argument is not of appropriate type, attempt to coerce it LPVARIANT pArgTemp = &rgTempVars[iArg]; ASSERT(pArgTemp->vt == VT_EMPTY); SCODE sc = GetScode(VariantChangeType(pArgTemp, pArg, 0, vt)); if (FAILED(sc)) { // argument could not be coerced *puArgErr = iArg; return sc; } ASSERT(pArgTemp->vt == vt); pArg = pArgTemp;}
|
Additional reference words: 1.50 2.50
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |