PDA

Просмотр полной версии : Очистка выделенной памяти при работе с DLL



Borys
14.07.2004, 15:55
Итак, есть длл, в которой находится форма. Она экспортирует ф-ю, которая и показывает эту форму.


HWND __stdcall ShowForm(LPCSTR phone, HWND hndl, LPCSTR name)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
OfficeForm* pdlg;
pdlg = new OfficeForm();
if (pdlg!=NULL)
{
BOOL ret = pdlg->Create(IDD_OFFICEFORM_DIALOG, pdlg->FromHandlePermanent(hndl));
if(!ret) //Create failed.
{
AfxMessageBox("Error creating Dialog");
return NULL;
}
pdlg->SetWindowPos(pdlg->FromHandlePermanent(hndl), 100, 100, 10, 10, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
pdlg->parenthwnd=hndl;
pdlg->ShowWindow(SW_SHOW);
return (pdlg->GetSafeHwnd());
}
else
return NULL;
}

В диалоге, который показывает эта функция, при нажатии на кнопку "Закрыть" происходит следующее:


EndDialog(0);
::SendMessage(parenthwnd,WM_USER+97, 0,0);

Сообщение посылается на главное окно, которое и открывает форму из длл, для того, чтоб оно вызвало FreeLibrary, так как форма и длл больше не нужна.
Вопрос: должно ведь где-то быть delete pdlg;
Обязательно ли для этого писать новую функцию, которую будет эткпортировать длл, или это можно сделать в имеющейся (очень не хочется изменять интерфейс).
И вообще, что вы посоветуете предпринять, чтоб очистить выделенную память.

Eugie
14.07.2004, 16:11
Удалять созданный объект, конечно, надо - если все делать по правилам:)

Можно так: сделать переменную pdlg глобальной (т.е.вынести на уровень модуля), написать процедуру DllMain и в ней на событие DLL_PROCESS_DETACH вызывать delete pdlg.

Romeo
14.07.2004, 17:58
А ещё есть такая важная вещь, как смартпоинтеры. Их как раз и следует использовать в подобных случаях, чтобы не было memory leak'ов :)

Borys
19.07.2004, 13:25
У меня длл с использованием MFC, там DllMain как-то спрятана. Тоесть ее не видно, если пытаешся написаит свою--пишет, что переопределение функции.
Вот скажите еще такое: у меня ведь есть дескриптор окна в длл, если я сделаю DestroyWindow, это решит проблему, тоесть освободит выделенную память в длл.

Eugie
19.07.2004, 17:01
А ещё есть такая важная вещь, как смартпоинтеры

Romeo, тогда уж лучше сразу перейти на .NET :)

Borys, если у тебя т.н. регулярная MFC dll, то в ней должен быть определен класс- наследник CWinApp, а у него есть методы InitInstace/ExitInstance. Можно сделать еще проще: не создавать объект pdlg динамически с помощью new, а сразу объявить статически OfficeForm dlg на уровне модуля - тогда он автоматически будет разрушен по завершении программы.


Вот скажите еще такое: у меня ведь есть дескриптор окна в длл, если я сделаю DestroyWindow, это решит проблему, тоесть освободит выделенную память в длл.

Не решит: DestroyWindow разрушит окно как объект Windows - этого было бы достаточно, если бы ты не использовал MFC. Но раз ты создал MFC-объект типа OfficeForm, то память, выделенная под него, тоже должна быть корректно освобождена.

Borys
19.07.2004, 17:24
Спасибо за ответы.
Мне интересно, неужели чтоб убить MFC клас унаследованный от CDialog нужно делать DestroyWindow а потом еще delete?

Eugie
19.07.2004, 18:10
Мне интересно, неужели чтоб убить MFC клас унаследованный от CDialog нужно делать DestroyWindow а потом еще delete?

Если MFC-wrapper WinAPI объекта (в данном случае окна) был создан динамически - именно так.

Borys
19.07.2004, 18:24
Спасибо.