![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
падение программы при выгрузке 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... а она тут опа и выгружается... т.е. программа продолжается "в никуда".
описАлся... сорри