Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: COM/DCOM/ActiveX/ATL/CORBA > В каких случаях интерфейс освобождать не надо


Автор: nerdy_weirdie 23.1.2011, 23:58
Надо ли освобождать интерфейсы, полученные методами вроде
HRESULT IHTMLFrameBase2::get_contentWindow(IHTMLWindow2 **p);
http://msdn.microsoft.com/en-us/library/aa752409
IHTMLDocument2::get_parentWindow() ;
Очень хотелось бы найти обоснование из мсдна.

Автор: RastaDja 24.1.2011, 10:41
nerdy_weirdie если вы используете в качестве указателя CComPtr, то не надо.

Во всех остальных случаях - надо, так как по стандарту все методы get возвращают указатель и делают AddRef() перед возвратом. Тоесть освобождать обьект должен клиент.

Автор: Cheloveck 24.1.2011, 12:21
Если использовать директиву #import или если заголовочные файлы сфоримрованы подобным образом, то велика вероятность того, что в них (в заголовочных файлах) будут объявлены врапперы на методы интерфейсов, которые будут возвращать значения (вместо HRESULT то, что указано последним параметром как [out, retval] или void) в виде смартпойнтера, которые дефайнятся в тех же файлах. Их высвобождать не надо. Также не надо освобождать, если используешь смартпойнторы напрямую, как сказал RastaDja. Во всех остальных случаях надо.

Добавлено через 3 минуты и 27 секунд
http://life-dev.blogspot.com/2010/12/com-activex-visual-c.htmlесть пример использования сгенерированных врапперов.

Автор: nerdy_weirdie 26.1.2011, 07:53
Смартпоинтеры не трогаем, с ними всё понятно.
я вот какую странную вещь наблюдаю:

Код

void Job(IWebBrowser2Ptr& pBrowser)
{
    IDispatchPtr pDisp = NULL;
    if (pBrowser)
    {
        HRESULT hr=pBrowser->get_Document(&pDisp);
        if (pDisp != NULL )
        {
            IHTMLDocument3Ptr pHTMLDocument3(pDisp);
            if (pHTMLDocument3)
            {
                DoTheJob(pHTMLDocument3);
            }
        }
    }
}

На момент вызова Release() в деструкторе смартпоинтера pDisp, интерфейс уже оказывается освобожденным и вызов влечет эксепшн
Код

First-chance exception at 0x7c812aeb in Test.exe: 0x80010108: Вызванный объект был отключен от клиентов.

Как такое может быть? где интерфейс успел освободиться?

Автор: Cheloveck 26.1.2011, 10:58
Цитата(nerdy_weirdie @  26.1.2011,  07:53 Найти цитируемый пост)
IHTMLDocument3Ptr pHTMLDocument3(pDisp);

Сделай вместо этого просто QueryInterface

Автор: xvr 26.1.2011, 12:00
Как описан тип IHTMLDocument3Ptr ?

Автор: Cheloveck 26.1.2011, 15:00
xvr, они, обычно, так описывают
Код

_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, __uuidof(HTMLDocument3));

Это http://msdn.microsoft.com/en-us/library/417w8b3b%28VS.80%29.aspx. Макросом дописывается Ptr.

Автор: xvr 26.1.2011, 16:08
Цитата(Cheloveck @  26.1.2011,  15:00 Найти цитируемый пост)
Это стандартный смартпойнтер для COM объектов. 

Т.е. CComPtr<IHTMLDocument3>.
Тогда действительно неправильно, тут нужен CComQIPtr<IHTMLDocument3>

Автор: nerdy_weirdie 26.1.2011, 16:33
   
Верно, этот тип унаследован от _com_ptr_t при помощи макроса
_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, __uuidof(HTMLDocument3));
В МСДНе написано что его конструктор вызывает QueryInterface()
http://msdn.microsoft.com/en-us/library/417w8b3b%28v=vs.80%29.aspx

Автор: RastaDja 26.1.2011, 17:20
если что неправильно скажу, то извиняюсь заранее.

Цитата

IHTMLDocument3Ptr pHTMLDocument3(pDisp);

pHTMLDocument3 выходит из области видимости оператора if (pDisp != NULL ), поэтому удаляется, ведь он смартпоинтер

Автор: xvr 26.1.2011, 18:39
Цитата(RastaDja @  26.1.2011,  17:20 Найти цитируемый пост)
pHTMLDocument3 выходит из области видимости оператора if (pDisp != NULL ), поэтому удаляется, ведь он смартпоинтер 
Это не страшно, т.к. выше есть еще один смартпоинтер (pDisp), который продолжает держать интерфейс.
А вот то, что его (pHTMLDocument3) извлекли не через QueryInteface - криминал



Автор: nerdy_weirdie 27.1.2011, 05:26
Через QueryInteface извлекли. Пруфлинк: http://msdn.microsoft.com/en-us/library/h3t4kcat%28v=vs.80%29.aspx

Автор: xvr 27.1.2011, 08:30
Цитата(nerdy_weirdie @ 27.1.2011,  05:26)
Через QueryInteface извлекли. Пруфлинк: http://msdn.microsoft.com/en-us/library/h3t4kcat%28v=vs.80%29.aspx

Действительно. Тогда смотрите, что происходит в DoTheJob. Не позвали ли там случайно CoUninitialize или не загасили ли случайно WebBrowser
Кстати - 
Цитата

0x80010108: Вызванный объект был отключен от клиентов.
это RPC_E_DISCONNECTED - очень похоже как раз на 2й случай (умер удаленный COM сервер, сам объект то остался). 

Автор: nerdy_weirdie 27.1.2011, 17:46
Цитата(xvr @ 27.1.2011,  08:30)
это RPC_E_DISCONNECTED - очень похоже как раз на 2й случай (умер удаленный COM сервер, сам объект то остался).

А происходит ли в этом случае утечка каких-либо ресурсов? Или они вместе с сервером освобождаются?

Автор: xvr 27.1.2011, 20:36
Цитата(nerdy_weirdie @  27.1.2011,  17:46 Найти цитируемый пост)
А происходит ли в этом случае утечка каких-либо ресурсов?
Может произойти

Цитата(nerdy_weirdie @  27.1.2011,  17:46 Найти цитируемый пост)
Или они вместе с сервером освобождаются?
Со стороны сервера - освобождаются. Со стороны клиента могут и застрять (до выхода из клиента)


Автор: nerdy_weirdie 28.1.2011, 16:57
Есть утечки. Интернет Эксплорер разбухает в памяти и создает немереное количество потоков и евентов. Как такое вообще дебажить, как отлавливать? 

Как вообще выяснить, какие ком-вызовы приводят к этим утечкам? Поотдельности ни один поток моей программы не вызывает выделения этих ресурсов.

Автор: xvr 28.1.2011, 20:28
Цитата(nerdy_weirdie @  28.1.2011,  16:57 Найти цитируемый пост)
Как вообще выяснить, какие ком-вызовы приводят к этим утечкам? 

Должны быть соответствующие тулзы. К сожалению кроме той программы, ссылку на которую я вам уже давал, они мне неизвестны  smile Надо искать  smile 

Автор: log584 29.1.2011, 09:14
Если я правильно понял насчет инструментов,то у меня на установочном диске MS VC++ 6 есть прога, которая встраивается в саму IDE и как раз она то и предназначена специально для анализа и мониторинга утечек. NuMega Boundschecker C++ Edition.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)