Почему все ссылки на мой объект IDispatch не освобождаются? - PullRequest
3 голосов
/ 18 августа 2011

Я размещаю элемент управления 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 Ответ

2 голосов
/ 18 августа 2011

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

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

...