Выгрузить Dll, в которой используется модуль данных
При работе с длл в которой загружается форма и дата модуль, по окончании работы длл из памяти не выгружается. Завершение работы приложения не помогает.
А как она загружается, и как выгружается?
Если вызов FreeLibrary тем или иным способом происходит, после этого любые адреса, связанные с DLL, становятся неопределенными. Короче, FreeLibrary выгружает DLL железно. Сам подумай - иначе бы у тебя Винда не работала ;)
А как она загружается, и как выгружается?
Если вызов FreeLibrary тем или иным способом происходит, после этого любые адреса, связанные с DLL, становятся неопределенными. Короче, FreeLibrary выгружает DLL железно. Сам подумай - иначе бы у тебя Винда не работала ;)
Если не ошибаюсь, FreeLibrary уменьшает счётчик ссылок на dll, а когда этот счётчик становится нулевым - отключает dll от адресного пространства вызывающего процесса, после чего handle этой dll в этом процессе делается недействительным. При этом другие процессы, загрузившие dll, продолжают её использовать.
Если не ошибаюсь, FreeLibrary уменьшает счётчик ссылок на dll, а когда этот счётчик становится нулевым - отключает dll от адресного пространства вызывающего процесса, после чего handle этой dll в этом процессе делается недействительным.
Согласен, все это делается в рамках одного процесса.
Только спрашивающий вроде не говорил, что у него одна и та же DLL может грузиться в нескольких местах программы или в одном месте несколько раз...
Может быть, проблема как раз в использовании содержимого Data Module? Не закрываются базы, или ещё что в этом духе? А если владелец - dll?
Да нет вроде все закрывается - я обрабатываю событие модуля onDestroy - и в нем проверяю соединение. Модуль создается имея в качестве владельца форму и в событии onClose формы выполняется delete. Удаление вроде происходит корректно.
Длл загружается один раз используя LoadLibrary - но FreeLibrary почемуто не отрабатывает - я думаю - возможно это связано с тем, что в ноды дерева на форме помещаются объекты вида (TObject*)(new AnsiString(Quary1->FieldByName("Field")->AsString)), может проблема в том что их необходимо явно разрушить? Сейчас попробую и напишу.
Ничего не понимаю - если не устанавливать соединение с базой - все работает нормально. Форма закрывается и никаких проблем. Если установить соединение - длл не выгружается из памяти. При этом я закрываю соединение - в чем проблема?
Возможно проблема в указателе на экземляр DataModul. Похожая пробема была, также в dll. При обращении MyDataModul->компонент->свойство, создавалось такое впечатление, существует второй экземпляр класса TMyDataModul, короче вообще всякая ерунда. Долго удивлятся не было времени, поэтому все обращения к MyDataModul заменил на this. Облегчение наступило сразу же..
А в отладке, в dll все проходит нормально?
Возможно проблема в указателе на экземляр DataModul. Похожая пробема была, также в dll. При обращении MyDataModul->компонент->свойство, создавалось такое впечатление, существует второй экземпляр класса TMyDataModul, короче вообще всякая ерунда. Долго удивлятся не было времени, поэтому все обращения к MyDataModul заменил на this. Облегчение наступило сразу же..
Честно говяря, ничего не понял...Где заменил на this? В функциях модуля? Так я там к компонентам напрямую обращаюсь. У меня из дата модуля реализованы две функции - одна пишет в базу, вторая читает. И вся работа с модулем построена на них.
А в отладке, в dll все проходит нормально?
Ну если не считать того, что процесс не завершается, то нормально.:)
Честно говяря, ничего не понял...Где заменил на this? В функциях модуля? Так я там к компонентам напрямую обращаюсь. У меня из дата модуля реализованы две функции - одна пишет в базу, вторая читает. И вся работа с модулем построена на них.
А где можно еще использовать this? Вот где можно там и заменил, везде в DATA модуле, обращение Label1->Text и MyDataModul->Label1->Text заменил на this->Label1->Text.:)
Если дельфя, то self.Label1.Text.
Только не спрашивай какой в этом смысл..:)
Ну если не считать того, что процесс не завершается, то нормально.:)
Я думал что в отладке видно почему процесс тормозиться..:)
До выход из функции dll так понимаю дело не доходит?
Я думал что в отладке видно почему процесс тормозиться..:)
До выход из функции dll так понимаю дело не доходит?
Да в том, то все и дело, что не доходит. Судя по всему в момент вызова FreeLibrary процесс виснет. Почему, хоть убей понять не могу.
Да в том, то все и дело, что не доходит. Судя по всему в момент вызова FreeLibrary процесс виснет. Почему, хоть убей понять не могу.
Фигня все это с DataModule, ничего он держать не может. У нас в аналогичном проекте все работало как часы, причем среда выполнения была посложнее...
Единственное, что приходит в голову - клиентские библиотеки для доступа к базе данных, если компонент соответствующей базы данных расположен непосредственно на DataModule. Обычно доступ к БД организуется динамической загрузкой клиентской библиотеки, и не факт, что выгружается при закрытии всех соединений. Она и может "держать" библиотеку. Если есть исходники компонентов доступа к БД, можно попробовать порыться там.
Единственное, что приходит в голову - клиентские библиотеки для доступа к базе данных, если компонент соответствующей базы данных расположен непосредственно на DataModule. Обычно доступ к БД организуется динамической загрузкой клиентской библиотеки, и не факт, что выгружается при закрытии всех соединений. Она и может "держать" библиотеку. Если есть исходники компонентов доступа к БД, можно попробовать порыться там.
Такой вариант можно рассматривать как последнее прибежище отчаявшихся...
Прежде в свое коде нужно порыться. Представляешь, что бы было, если бы ты прав, прости за фамильярность..:) Такой клиент этой базы вообще бы не смог работать нормально..
Да в том, то все и дело, что не доходит. Судя по всему в момент вызова FreeLibrary процесс виснет. Почему, хоть убей понять не могу.
Handle модуля действительный перед вызовом FreeLibrary (GetModuleHandle)?Кроме этого, можно после FreeLibrary вызвать GetLastEror(), чтоб посмотреть в чем проблема.
Или вызвать по несколько раз подряд FreeLibrary?:D
Это все еще лучше чем:
...хоть убей понять не могу.
Handle модуля действительный перед вызовом FreeLibrary (GetModuleHandle)?Кроме этого, можно после FreeLibrary вызвать GetLastEror(), чтоб посмотреть в чем проблема.
Handle модуля действительный, я проверял, кроме того, я пытался использовать вызов вида FreeLibrary (GetModuleHandle("library.dll")) - проблема в том что FreeLibrary не завершает работу. Поэтому и GetLastEror() управления не получает.
FreeLibrary не завершает работу. Поэтому и GetLastEror() управления не получает.
Значит FreeLibrary освобождает какой-то объект, указатель на который неправильный. Я сперва для начала закомментировал бы все Delete/Free.
У тебя в проге, есть хоть одна из них?
Значит FreeLibrary освобождает какой-то объект, указатель на который неправильный. Я сперва для начала закомментировал бы все Delete/Free.
У тебя в проге, есть хоть одна из них?
Попробую.
Значит FreeLibrary освобождает какой-то объект, указатель на который неправильный. Я сперва для начала закомментировал бы все Delete/Free.
Блин, даже мне интересно стало, что это за объект такой у тебя в проге, который FreeLibrary не может освободить. Если найдешь, обязательно напиши в форум, в чем проблема была. Для общего, так сказать, развития...
Блин, даже мне интересно стало, что это за объект такой у тебя в проге, который FreeLibrary не может освободить. Если найдешь, обязательно напиши в форум, в чем проблема была. Для общего, так сказать, развития...
Проблема в том, что мне приходится использовать БДЕ-компоненты и судя по всему, при загрузке одной из длл и возникает проблема. Пока расклад такой - если по закрытии формы приложения-хоста или в длл по завершении функции я выполняю:
FreeLibrary(GetModuleHandle("bantam.dll"));
FreeLibrary(GetModuleHandle("idr20009.dll"));
FreeLibrary(GetModuleHandle("newdot~1.dll"));
FreeLibrary(GetModuleHandle("hplun.dll"));
А после
FreeLibrary(GetModuleHandle("labourdis.dll"));
Все проходит на ура - правда если в среде разработки - вылетает исключение о access violation - но это уже не столь критично в данной ситуации, надо разобратся - гдето, что то удалил чересчур рано...:) но память четко очищается. Сейчас протестирую на VB - посмотрим как отработает.
Список длл я выволок из IS - динамически просканил и прописал. Последовательность выгрузки в моем случае играет роль, по крайней мере для первых двух. Вот такие пирожки с котятами. Может не все конечно и нужно освобождать...:) но как говорится гулять так гулять.
Все проходит на ура - правда если в среде разработки - вылетает исключение о access violation - но это уже не столь критично в данной ситуации, надо разобратся - гдето, что то удалил чересчур рано...:) но память четко очищается.
Вот тебе и прибежище отчаявшегося. По коду вроде самое оно.
Кстати, подлинный корень проблемы может быть зарыт еще глубже. У тебя программа компилится с библиотеками времени выполнения или standalone?
Вот тебе и прибежище отчаявшегося. По коду вроде самое оно.
Кстати, подлинный корень проблемы может быть зарыт еще глубже. У тебя программа компилится с библиотеками времени выполнения или standalone?
Я пробовал и так (с RTL) и без, по сути разницы никакой - если я самостоятельно не выгружу библиотеки - из них кстати значение имеют только две первые - моя библиотека из памяти выгружена не будет.
Я пробовал и так (с RTL) и без, по сути разницы никакой - если я самостоятельно не выгружу библиотеки - из них кстати значение имеют только две первые - моя библиотека из памяти выгружена не будет.
Хм. Вообще-то для BDE, вероятно, никакой разницы и не должно быть. Она сама все равно в виде отдельных модулей грузится. В программе - только интерфейсы к ней.
Кстати, а ты не пробовал покопаться с низкоуровневым интерфейсом BDE (Dbi-функции). Вполне возможно, что у нее есть цивилизованный способ...
Кстати, а ты не пробовал покопаться с низкоуровневым интерфейсом BDE (Dbi-функции). Вполне возможно, что у нее есть цивилизованный способ...
Возможно, я BDE использую крайне редко, будет время буду разбираться. Но проблема выгрузки модулей, которые используют TDataModule вобще-то достаточно актуальна, судя по всему, прийдется разбираться как отрабатывает деструктор класса производного, и базового. Скорее всего проблема в этом.
Но проблема выгрузки модулей, которые используют TDataModule вобще-то достаточно актуальна, судя по всему, прийдется разбираться как отрабатывает деструктор класса производного, и базового.
Блин, так в том-то и дело, что это проблема только BDE. У нас аналогичное приложение, использующее ODAC, работает на ура.
Могу даже предположить, "все проблемы происходят от преждевременной оптимизации" (с) не помню уже.
BDE пытается держать в памяти только одну копию самой себя, и шарить ее между процессами. Помнишь предупраждение после изменения настроек в BDE Administrator? А у тебя, похоже, счетчик ссылок не уменьшается. Когда ты выгружаешь библиотеки в нахаловку, это приводит к краху IDE в дизайне именно поэтому.
Могу даже предположить, "все проблемы происходят от преждевременной оптимизации" (с) не помню уже.
"Преждевременная оптимизация - корень всех бед" - слова Дональда Кнута :)