Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

падение программы при выгрузке DLL'ки.... [D7, Win2k]


casper24 ©   (2004-12-15 04:03:00) 

при открытии DLL (Loadlibrary)

в процедуру библиотеки передаю указатель на процеду в основной программе. Для "общения" между библиотекой и основной программой.

DLL
------

var
MainProcedure:Procedure (p:pchar);
...
procedure Open(Proc:Pointer);
begin
...
@MainProcedure:=Proc;
...
end;

Допустим
при выполнении в библиотеки
MainProcedure('OK')
основная программа "понимает" что какие-то функции выполнины успешны...

Основная программа
-------------------

procedure GetDataFormDll(p:pchar) //процедура обработки данных от DLL
begin
....
if strpas(p)='OK'
then showmessage('все нормально');
..
end;

//вот здесь происходит загрузка и передача указателя процедуры в DLL
procedure LoadDLL;
begin
@open:=nil;

DLLhandle:=Loadlibrary('my.dll');
if dllhandle>=32 then begin
open:=GetProcAddress(dllHandle,'Open');
if open<>nil then
Open(@GetDataFromDLL);
end;
end;


Так вот все бы нормально, работает стабильно, НО ...
в один прекрасный момент надо чтобы основная программа выгрузила библиотеку по команде из этой самой DLL.

Допустим....

DLL
----------------
ModuleProcedure('KILL');

Основная программа
---------------------------
procedure GetDataFromDll(p:pchar);
begin
...
if strpas(p)='KILL' then
FreeLibrary(DllHandle);
...
end; <- и вот при трасировке на этом месте происходит конкретный упад и библиотеки и основной программы.

я вприципе понимаю почему, т.е. процедуру GetDataFromDll я вызываю из процедуры, после ее завершения должна продолжится dll... а она тут опа и выгружается... т.е. программа продолжается "в никуда".
Как избежать такого дела, не меняя системы передачи данных?

PS: ой как не хочется пользоваться сообщениями...ужас...


SammIk   (2004-12-19 18:01:00) [1]

Можно и стек править.
Та чтоба в бабку или пробабку отпровляла.
Или в другую ф-ю.


casper24   (2004-12-19 17:21:00) [2]

все ок разобрался!
ВСЕМ СПАСИБО!

Реализовал callback ф-цию + PostMessage - работает как часы...


Leonid Troyanovsky   (2004-12-18 20:36:00) [3]


> SammIk ©   (18.12.04 20:11) [12]
> Скорее всего слетает из-за того, что:
> 1- Вызываешь из длл ф-ю в основном модуле.
> 2- выгружаешь либу
> 3- Из процедуры в основном модуле идет возврат, по адресу
> процедуры в длл'ке. НО ТАМ УЖЕ ничего НЕТ(((
> -----------
> Простыми средствами из этои ситуации не выбратся(((


Ясен пень. В такую ситуацию проще не забираться.
Т.е., выгружать ее надо после возврата из функции.
Чего уж проще?

--
С уважением, LVT.


SammIk   (2004-12-18 20:11:00) [4]

Скорее всего слетает из-за того, что:
1- Вызываешь из длл ф-ю в основном модуле.
2- выгружаешь либу
3- Из процедуры в основном модуле идет возврат, по адресу
процедуры в длл'ке. НО ТАМ УЖЕ ничего НЕТ(((
-----------
Простыми средствами из этои ситуации не выбратся(((
Тока если сделать так
UINT_PTR SetTimer(
 HWND hWnd,              // handle to window
 UINT_PTR nIDEvent,      // timer identifier
 UINT uElapse,           // time-out value
 TIMERPROC  // timer procedure
);
Где lpTimerFunc   - указательна твою процедуру


Leonid Troyanovsky   (2004-12-18 14:08:00) [5]


> casper24   (17.12.04 21:47) [10]

> прошу прощения... не увидел...
> реализовал,

> но вот проблема, все равно слетает... :(


Кривая реализация, вот и слетает.

--
С уважением, LVT.


casper24   (2004-12-17 21:47:00) [6]

Юрий Зотов ©

прошу прощения... не увидел...

реализовал,

но вот проблема, все равно слетает... :(


Юрий Зотов   (2004-12-17 02:58:00) [7]

> casper24   (15.12.04 11:50) [6]

Сорри, а Вы ответы читаете?


Leonid Troyanovsky   (2004-12-15 20:57:00) [8]


> casper24   (15.12.04 11:36) [5]
> а есть какие-то способы во время работы процедуры GetDataFromDll
> не доводить выполнения до стройки "end;"
> а как-то убивать ее...


Если само приложение дельфийское, то прервать выполнение
кода в библиотеке (или в том коде, который вызывается ею из
приложения, т.е. GetDataFromDll) можно процедурой Abort.

Т.е., в приложении достаточно сделать:


var
  lib: THandle;
begin
  lib := LoadLibrary();
  @initdll := GetProcAddress(..);
  @p1 := GetProcAddress(..);
  @p2 := GetProcAddress(..);
  ..
  try
    initdll(@GetDataFromDll); // передаем адрес callback
    p1(..); // вызов библиотечной функции
    p2(..); // вызов библиотечной функции
    ..
  finally
    FreeLibrary(lib);
  end;

--
С уважением, LVT.


Digitman   (2004-12-15 12:50:00) [9]


> casper24   (15.12.04 11:36) [5]
> а есть какие-то способы во время работы процедуры GetDataFromDll
> не доводить выполнения до стройки "end;"
> а как-то убивать ее...


не занимайся ерундой.
за строкой "end", возможно, скрывается не одна-единственная маш.инструкция, сгенерированная компилятором.

посылка/обработка асинхронного сообщения, о которой упомянул ЮЗ в [2] - простейшее и наилучшее решение задачи.


casper24   (2004-12-15 11:50:00) [10]

вопрос!!!!

А что есть при компаде 'KILL' процедура основной программы
GetDataFromDll посылается самой себе PostMessage и там уже обрабатывает ее на удаление?

ща пойду реализовывать...


casper24   (2004-12-15 11:36:00) [11]

а есть какие-то способы во время работы процедуры GetDataFromDll не доводить выполнения до стройки "end;"
а как-то убивать ее...


Leonid Troyanovsky   (2004-12-15 09:59:00) [12]


> casper24   (15.12.04 04:03)  

> в процедуру библиотеки передаю указатель на процеду в основной
> программе. Для "общения" между библиотекой и основной программой.
..
> Как избежать такого дела, не меняя системы передачи данных?


Менять, все равно, придется.
Сделать можно так. Приложение, загрузив библиотеку,
вызывает из нее функции, содержащие параметр  var CanUnloadNow: LongBool
(или, скажем,  var NextStep: Longint).
После вызова любой из функций библиотеки приложение
анализирует возвращаемый результат и выгружает библиотеку
при необходимости.

--
С уважением, LVT


SVM (Perm)   (2004-12-15 09:09:00) [13]

DLLhandle:=Loadlibrary('my.dll');
if dllhandle>=32then ...

Это почему так?


Юрий Зотов   (2004-12-15 04:22:00) [14]

> ой как не хочется пользоваться сообщениями...ужас...

А, пожалуй, это и есть самое простое решение - из GetDataFromDll вызвать PostMessage, а в обработчике уже выгружать DLL.


casper24   (2004-12-15 04:05:00) [15]

я вприципе понимаю почему, т.е. процедуру GetDataFromDll я вызываю из DLL, после ее завершения должна продолжится dll... а она тут опа и выгружается... т.е. программа продолжается "в никуда".

описАлся... сорри


Наверх

Титульная страница Поиск, карта сайта Написать письмо