Почему все ссылки на мой объект 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, ¶ms, 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 свойству или другому объекту.