Почему все ссылки на мой объект IDispatch не освобождаются?

Я размещаю элемент управления IWebBrowser2 в моей программе на C++, используя только обычный Win32 (без mfc, atl, wtl и т. Д.). На DISPID_NAVIGATECOMPLETE2 я добавляю пользовательский объект для доступа из JavaScript, запущенного на отображаемой веб-странице.

Чтобы добавить пользовательский объект, я вызываю InvokeEx с DISPATCH_PROPERTYPUT и структуру DISPPARAMS с указателем на мой пользовательский объект.

Во время вызова InvokeEx вызывается функция AddRef моего пользовательского объекта, и я увеличиваю его счетчик ссылок. Но объект никогда не получает вызов своей функции Release, поэтому счетчик ссылок никогда не уменьшается до нуля.

Кто отвечает за вызов Release() после вызова AddRef() в InvokeEx?

РЕДАКТИРОВАТЬ: (Добавление некоторого кода)

Это код, который добавляет мой пользовательский объект в IHTMLWindow2. custObj указывает на мой пользовательский объект

IHTMLWindow2 *win = NULL;
GetDoc()->get_parentWindow(&win);
IDispatchEx *winEx = NULL;
win->QueryInterface(&winEx);

DISPID dispid;
HRESULT hr = winEx->GetDispID(objName, fdexNameEnsure, &dispid); //objName is "JSObject"

DISPID namedArgs[] = {DISPID_PROPERTYPUT};
DISPPARAMS params;
params.rgvarg = new VARIANT[1];
params.rgvarg[0].pdispVal = custObj;
params.rgvarg[0].vt = VT_DISPATCH;
params.rgdispidNamedArgs = namedArgs;
params.cArgs = 1;
params.cNamedArgs = 1;

hr = winEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL); 

Это объект, который я добавляю (некоторые частные члены были опущены для краткости)

class JSObject : public IDispatch {
private:
    long ref;
public:
    JSObject();

    // IUnknown
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
    virtual ULONG STDMETHODCALLTYPE AddRef();
    virtual ULONG STDMETHODCALLTYPE Release();

    // IDispatch
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid,
        ITypeInfo **ppTInfo);
    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,
        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
    virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
        LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
        EXCEPINFO *pExcepInfo, UINT *puArgErr);
};

РЕДАКТИРОВАТЬ 2:

Теперь, когда он, кажется, работает как надо, я решил поставить его на github.

https://github.com/Tobbe/CppIEEmbed. Пожалуйста, раскошелиться и улучшить, если можете:)

1 ответ

Решение

Ну, вы назначаете собственность, не так ли? Пока это свойство существует и ссылается на ваш объект, к нему будет добавлена ​​ссылка.

Если вы хотите, чтобы удаленный объект освободил вашу ссылку, вы должны присвоить NULL свойству или другому объекту.

Другие вопросы по тегам