![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
корректное завершение [Delphi, Windows]
matroskin66 © (2007-09-11 19:41:00)здравствуйте. использую KOL для написания dll. в программе вызываю процедурку, показывающую форму из dll. форма отображается не модально. использую следующий код:
procedure ShowForm;
begin
if Applet <> nil then Applet.Free;
Applet := nil;
AppletTerminated := false;
Applet := NewApplet('');
NewMyForm(MyForm, Applet);
MyForm.Form.Show;
Applet.Visible := false;
Run(Applet);
Applet.Free;
Applet := nil;
AppletTerminated := false;
end;
А теперь суть проблемы. Если закрыть форму, и выгрузить dll, всё будет хорошо. Но если выгружать dll не закрывая KOL форму, то вылетает ошибка и программа вырубается :( Пробовал перед выгрузкой использовать метод MyForm.Form.Close но всё равно ошибка остаётся. Пожалуйста подскажите как быть.
Delphuk (2007-12-09 13:11:00) [21]Владимир Кладов, я проверил, с VLC таких проблем нет, никакие ошибки не вылетают т.е. код в стеке норм весь выполняется и только потом уже происходит выгрузка библиотеки. Вот основной код моей демки на VLC:
//процедура выполняется при инициализации плагина
procedure OnInitialize;
begin
Form1 := TForm1.Create(nil);
Form1.Show;
Called := true;
end;
//процедура вызывается в момент получения сообщения, что сейчас плагин будет отключен
procedure OnFinalize;
begin
if Called
then
begin
Form1.Close;
Form1.Free;
MessageBox(0, 'good', 'msg', 0);
Called := false;
end;
end;
Всё прекрасно работает, а вот подобный код в KOL (чуть выше я уже писал код) приводит к ошибке и вылету хост-приложения. Владимир, пожалуйста обратите на это внимание.
Delphuk (2007-12-09 12:54:00) [22]саму dll я не выгружаю (не могу т.к. хост-приложение не моё) я только реагирую на событие перед выгрузкой dll, и dll выгружается только после того, как закончится обработка данного события. Сделаю небольшую демку на VLC и посмотрю, какая будет реакция в подобной же ситуации, потом сообщу. Но всё же, мне кажется, что проблема с Апплетом.
Vladimir Kladov (2007-12-09 12:46:00) [23]Сильно подозреваю, что происходит выгрузка dll в тот момент, когда ещё есть в стеке код, который сам из этой dll. Вы пытаетесь закрыть форму и выгрузить dll из самой dll?
Delphuk (2007-12-09 11:41:00) [24]Пишу под Delphi 6.
> Кстати, включили поддержку debug dcu + информации для TurboDebuger'а
> (в закладке Linker)? Помогает.
Да, конечно это включаю, но результата нет :( Мне вот что интересно, ведь если ручками закрывать форму, то всё норм. Там кнопка с полностью идентичным кодом SettingsForm.Form.Close; А вот если просто вызывать этот метод, то вылетает хост-приложение. Я уже даже попробовал извратиться и программно нажать на кнопку закрытия формы, но результат тот же :(
Vladimir Kladov (2007-12-09 11:10:00) [25]Попробуйте другую версию Delphi. И это серьёзный совет. То, что не идёт на D7, вполне может сработать на D6, например. Кстати, включили поддержку debug dcu + информации для TurboDebuger'а (в закладке Linker)? Помогает.
Ещё одни вариант: отладка под MS VC++. Тяжеловато лазить по дизасм-коду, но если очень хочется, то можно.
И последний вариант - логи.
Delphuk (2007-12-09 10:40:00) [26]Отлаживать dll не получается. Прописываю хост приложение, включаю все необходимые опции проекта, указываю необходимые пути для исходников и тд. При запуске пошаговой отладки, через несколько секунд вылетает окошко с ошибкой "External exception EEFFACE" после чего дэльфи можно выключить только убив сам процес дэльфи.
Vladimir Kladov (2007-12-08 23:25:00) [27]Я как помогу, я же с плагинами не работаю. Вот я пример у себя (с полгода как или больше) положил. Там есть проблема? (А ведь там даже есть вариант с вызывальщиком на C).
PAS_VERSION - пробовали? Отлаживать, что вылетает - пробовали? Можно ведь включить пошаговую отладку со стороны DLL.
Delphuk (2007-12-08 21:38:00) [28]Удалено модератором
Delphuk (2007-12-08 21:37:00) [29]Столкнулся с полностью идентичной проблемой. Использую KOL+MCK для написания плагина для RnQ (хост приложение). Вызываю окно плагина (не модально) точно так же, как в демке:
procedure ShowSettings;
begin
CanShow := false; //булевская переменная для контроля показа только одной копии формы
if Applet <> nil then Applet.Free;
Applet := nil;
AppletTerminated := false;
Applet := NewApplet('');
NewSettingsForm(SettingsForm, Applet);
SettingsForm.Form.Show;
Applet.Visible := false;
Run(Applet);
Applet.Free;
Applet := nil;
AppletTerminated := false;
CanShow := true;
end;
Использую вот такой код для вызова окна моего плагина:
begin
if CanShow
then
ShowSettings
else
SettingsForm.Form.Show;
end;
Проблема в том, что если отключать плагин при открытой форме, то вылетает ошибка и хост приложение "умирает". А если сначала "вручную" закрыть форму и только потом отключать плагин, то всё норм. Логично, что так и должно быть и перед отключением нужно закрывать форму, но...
Перед отключением генерируется событие, что сейчас плагин будет отключен. Тут я проверяю, открыта ли форма плагина и если открыта, то закрываю её:
procedure OnFinalize;
begin
if not CanShow
then
begin
ShowMessage('off....');
SettingsForm.Form.Close;
end
else
MessageBox(0, 'Отключено успешно', 'Отключение', MB_OK);
end;
Как и положено, если форма закрыта, то выводится соотв. сообщение и плагин благополучно отключается. А если форма открыта, то выводится другое сообщение, но после выполнения SettingsForm.Form.Close; вылетает ошибка и хост приложение вылетает.
Ещё раз хочу акцентировать внимание на том, что если ручками закрыть форму, то никаких проблем нет. Владимир Кладов, пожалуйста помогите, ошибка точно где то со стороны Апплета.
Dimaxx (2007-09-26 10:17:00) [30]Давно что-то не использовал формы из dll, поэтому хочу спросить на будущее: это относится к динамически загружаемым dll или к статическим тоже? Давно как-то делал приложение, в котором статически вызывалась ф-ция с формой. Так вот все нормально открывалось и закрывалось. Но если хотя бы один раз открыть-закрыть форму из dll - основное приложение падало при закрытии себя с ошибкой 216. Вроде все делал как в примере.
Кстати эта ошибка 216 лезла раньше изо всех щелей.
Vladimir Kladov (2007-09-24 18:04:00) [31]Я проблемы не вижу. Выгружать dll, не завершив работу с её функциями, абсолютно неверно. Это не только KOL касается. Сам недавно напарывался: если неожиданно выгрузить либу (кажется, это была opengl), то программа падает с большим грохотом при попытке обратиться к ее функциям. И это понятно: по тем адресам больше нет исполняемого кода. Вообще ничего нет. А адрес функции остался.
thaddy (2007-09-24 03:13:00) [32]You could use my interceptors to trap unloadlibrary:
http://thaddy.co.uk/koldetours.zip
But that technique is not recommended (although it works!)
matroskin66 (2007-09-23 23:17:00) [33]Владимир Кладов, вся надежда только на вас :-[ проясните ситуацию.
Так есть решение проблемы или нет? Скажите плз.
matroskin66 (2007-09-11 23:49:00) [34]Владимир Кладов, вся надежда только на вас :-[ проясните ситуацию.
mdw (2007-09-11 22:09:00) [35]Перечитал еще раз [1] немного не в тему ответил, но ноги все равно от туда растут...
mdw (2007-09-11 22:08:00) [36]Никак. Проблема давно висит, и пожалуй решить (если возникнет желание) может только автор. Долго копался, но проблема, насколько понял, в том что нужно создавать новый Applet, т.е. еще один обработчик событий. Не выходит создать полностью адекватную форму из Dll. Если закрыть основное приложение до закрытия формы из Dll, то Applet из Dll остается жить своей жизнью, а в результате приложение остается висеть в памяти.