Почему я не могу вызвать интерфейс Release COM-объекта - PullRequest
0 голосов
/ 07 октября 2010

Я разрабатываю надстройку VC для VC6 и VC9.Следующие коды взяты из моих работ.В CViaDevStudio::Evaluate, после того как я позвонил pDebugger->Release() и все нормально.Но в CViaVisualStudio::ReadFromMemory, после того как я позвоню pDebugger->Release() или pProc->Release(), VC9 выдаст сообщение об ошибке с неопределенным номером ошибки.Я не знаю почему.Я думаю, что разумно вызывать Release() после того, как я использовал COM-объект.

/* VC6 */
class CViaDevStudio {
...
IApplication* m_pApplication;
};

BOOL    CViaDevStudio::Evaluate(char* szExp, TCHAR* value, int size)
{
    BOOL re = FALSE;
    IDebugger*  pDebugger = NULL;
    m_pApplication->get_Debugger((IDispatch**)&pDebugger);

    if (pDebugger) {
        ...
    }

exit:
        // The following code must be called, otherwise VC6 will complaint invalid access
        // when it's started again
    if (pDebugger)
        pDebugger->Release();

    return re;
}    

/* VC9 */
class     CViaVisualStudio {
    ...
    CComPtr<EnvDTE::_DTE> m_pApplication;
};

BOOL    CViaVisualStudio::ReadFromMemory(PBYTE pDst, PBYTE pSrc, long size)
{
    BOOL re = FALSE;
    EnvDTE::DebuggerPtr pDebugger;
    EnvDTE::ProcessPtr pProc;

    if (S_OK == m_pApplication->get_Debugger(&pDebugger)) {
        if (S_OK == pDebugger->get_CurrentProcess(&pProc)) {
            ...
            }
        }
    }

exit:
    // I don't know why the following enclosed with macros should not be called.
#if 0
    if (pDebugger)
        pDebugger->Release();
    if (pProc)
        pProc->Release();
#endif
    return re;
}

1 Ответ

2 голосов
/ 07 октября 2010
EnvDTE::DebuggerPtr pDebugger;

Обратите внимание, что объявление указателя отличается от того, как вы это делали в Evaluate. Это IDebugger * там. Класс DebuggerPtr - это класс-оболочка, сгенерированный директивой #import. Это умный указатель класса, он знает, как автоматически вызывать Release (). Даже если код генерирует исключения, он не пропустит указатель. Настоятельно рекомендуется. Вы найдете его документированным в библиотеке MSDN как класс _com_ptr_t.

...