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

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Borys
Сообщения: 18
Зарегистрирован: 09 июл 2004, 17:25
Откуда: Киев

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

Код: Выделить всё

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
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

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

Можно так: сделать переменную pdlg глобальной (т.е.вынести на уровень модуля), написать процедуру DllMain и в ней на событие DLL_PROCESS_DETACH вызывать delete pdlg.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А ещё есть такая важная вещь, как смартпоинтеры. Их как раз и следует использовать в подобных случаях, чтобы не было memory leak'ов :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Borys
Сообщения: 18
Зарегистрирован: 09 июл 2004, 17:25
Откуда: Киев

У меня длл с использованием MFC, там DllMain как-то спрятана. Тоесть ее не видно, если пытаешся написаит свою--пишет, что переопределение функции.
Вот скажите еще такое: у меня ведь есть дескриптор окна в длл, если я сделаю DestroyWindow, это решит проблему, тоесть освободит выделенную память в длл.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

А ещё есть такая важная вещь, как смартпоинтеры
Romeo, тогда уж лучше сразу перейти на .NET :)

Borys, если у тебя т.н. регулярная MFC dll, то в ней должен быть определен класс- наследник CWinApp, а у него есть методы InitInstace/ExitInstance. Можно сделать еще проще: не создавать объект pdlg динамически с помощью new, а сразу объявить статически OfficeForm dlg на уровне модуля - тогда он автоматически будет разрушен по завершении программы.
Вот скажите еще такое: у меня ведь есть дескриптор окна в длл, если я сделаю DestroyWindow, это решит проблему, тоесть освободит выделенную память в длл.
Не решит: DestroyWindow разрушит окно как объект Windows - этого было бы достаточно, если бы ты не использовал MFC. Но раз ты создал MFC-объект типа OfficeForm, то память, выделенная под него, тоже должна быть корректно освобождена.
Borys
Сообщения: 18
Зарегистрирован: 09 июл 2004, 17:25
Откуда: Киев

Спасибо за ответы.
Мне интересно, неужели чтоб убить MFC клас унаследованный от CDialog нужно делать DestroyWindow а потом еще delete?
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Мне интересно, неужели чтоб убить MFC клас унаследованный от CDialog нужно делать DestroyWindow а потом еще delete?
Если MFC-wrapper WinAPI объекта (в данном случае окна) был создан динамически - именно так.
Borys
Сообщения: 18
Зарегистрирован: 09 июл 2004, 17:25
Откуда: Киев

Спасибо.
Ответить