СОМ объекты
CComPtr<IHTMLImgElement>spImgEl; // указатель на интерфейс
CComPtr<IDispatch>spDisp; // --||--
for (long i=0; i<Img_ln; i++)
{
spImgEl = NULL; // обнуление указателя
spDisp = NULL;
ind.lVal = i;
spImgCol->item(ind,ind, &spDisp);
spDisp->QueryInterface(IID_IHTMLImgElement, (LPVOID*)&spImgEl);
spImgEl->get_src(&src);
}
вопрос в следующем: можно ли до начала цикла определить указатели на интерфейс а в теле цикла их обнулять? (в принципе так работает)
не повлечет ли это потер. самого объекта для автоматического Release();?
вопрос в следующем: можно ли до начала цикла определить указатели на интерфейс а в теле цикла их обнулять? (в принципе так работает)
А зачем их обнулять? По сути это же не указатель, а объект представляющий указатель на COM объект. И есть возможность проверять его валидность и так.
Кстати получить spImgEl (над названиями не мешело бы подумать), можно и с помощью объекта типа CComQIPtr<IHTMLImgElement, &IID_IHTMLImgElement>. Его класс специально для автоматического QueryInterface сделан.
а что в названии не так?
2. Обнулять нужно, т.к. он не раз используется в коде, не только в цикле.
3. CComQIPtr<IHTMLImgElement, &IID_IHTMLImgElement>. автоматом QueryInterface не подходит т.к. делается через IDispatch.
ПЫСЫ: а ответа на вопрос не прозвучало... :(
а что в названии не так?
Неинформативное
2. Обнулять нужно, т.к. он не раз используется в коде, не только в цикле.
Ну и что? при чем тут присвоение NULL внутреннему указателю? Проверить можно из без этого. А удалять вызовом Release().
Насчет присвоения - ничего плохого видимо не будет. Внутненний указатель просто станет NULL.
3. CComQIPtr<IHTMLImgElement, &IID_IHTMLImgElement>. автоматом QueryInterface не подходит т.к. делается через IDispatch.
Дык на сколько я помню CComQIPtr для того и создан чтобы автоматом получать объект например из того же IDispatch. Просто он сам вызывает QueryInterface.
spImgEl - "service-pointer-Imading-Element"
Release() автоматический при такой конструкции: CComPtr<...>spCom;
все дело в том что сначала методом item(...) передается в IDispatch, а затем уже в IHTMLImgElement.
вопрос: не потеряется ли "предыдущий" относительно цикла указатель для авто - Release(), если идет обнуление его в последующем шаге цикла?
Ну и. Я же говорю неинформативное. Я к тому, что невнятные сокращения не прибваляют информативности к названию, хотя мне впринципе оно и было понятно )
Release() автоматический при такой конструкции: CComPtr<...>spCom;
Ну автоматический Release() не отменяет ручного приминения (именно метода класса CComPtr .Release(), а ->Release() от интерфейса. )
все дело в том что сначала методом item(...) передается в IDispatch, а затем уже в IHTMLImgElement.
Вот в IHTMLImgElement как раз и можно в частности присваивать IDispatch через CComQIPtr
вопрос: не потеряется ли "предыдущий" относительно цикла указатель для авто - Release(), если идет обнуление его в последующем шаге цикла?
Ну на самом деле переприсваивание объекта без Release() не хорошо. И NULL тут впринципе то и не нужен.
компилятор ругается, и говорит что Release() недоступен для СComPtr
Release() - автоматический!!!
NULL нужен, т.к. при итеррации в цикле если указатель не NULL тогда на QueryInterface AV вылетает...
если понятно, то какое же оно не информативное? или писать полностью?
ПЫСЫ: я разобрался в реализации CComPtr - авто-Release() вызывается тогда когда указатель в NULL превращается, следовательно если при итеррции предыдущее значение обнулять, тогда происходит Release() объекта.
ATLINLINE ATLAPI_(IUnknown*) AtlComPtrAssign(__deref_out_opt IUnknown** pp, __in_opt IUnknown* lp)
{
if (pp == NULL)
return NULL;
if (lp != NULL)
lp->AddRef();
if (*pp)
(*pp)->Release();
*pp = lp;
return lp;
}
т.е. если указатель NULL, удаляется объект.
Да конечно )) Покажи код как вызываешь.
NULL нужен, т.к. при итеррации в цикле если указатель не NULL тогда на QueryInterface AV вылетает...
Именно для того чтобы не вылетал я и говорил надо делать Release()
если понятно, то какое же оно не информативное? или писать полностью?
Ну оно понятно, потому что я щас догадался из контектса. А мог бы и не быть догадливым. Вобщем конвенции нэйминга это конечно отдельная тема, но вот представь ты через пару лет этот код будешь смотреть - сразу все поймешь?
ПЫСЫ: я разобрался в реализации CComPtr - авто-Release() вызывается тогда когда указатель в NULL превращается
Ну скорее всего так и есть, я не помню уже, но такое поведение вполне логично. Потому и не падает. )
CComPtr<IDispatch>spDisp;
...
...
...
CComPtr<IHTMLElement>spEl;
spDisp->QueryInterface(IID_IDispatch, (LPVOID*)&spEl);
BSTR tag;
spEl->get_tagName(&tag);
spEl->Release(); // вот тут компилятор говорит что для CComPtr метод Release() is not accessible
ПЫСЫ: я ж ниче не придумываю, говорю как есть
spEl->Release(); // вот тут компилятор говорит что для CComPtr метод
Все правильно он говорит. ))
Надо просто писать spEl.Release(); а не spEl->Release(); я же говорил.
Чтобы вызвать именно метод Release объекта CComPtr, а не приватный метод итерфейса IUnknown.
Удобные, и с переопределенными операторами приисваивания, сравнения и т.п.
Удобные, и с переопределенными операторами приисваивания, сравнения и т.п.
спасибо, учту :)
к стати, spEl.Release(); тоже работает, за это отдельное спасибо!
(хотя наверно и в моем варинте тоже все правильно работало)