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

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

DllEntryPoint( .. DLL_PROCESS_DETACH .. ) => finalization ?


Страницы:   1 2

GuAV ©   (2004-12-29 21:41:00) 

Когда ОС вызывает DllEntryPoint с параметром DLL_PROCESS_DETACH, выполняется ли finalization модулей библиотеки или эти события не зависят друг от друга ?


GuAV   (2004-12-31 00:46:00) [1]

Palladin ©   (31.12.04 0:01) [21]
результаты нескольких вызовов LoadLibrary в одном и том же хостприложении


Это тоже сейчас проверил. Да, при повторном LoadLibrary не запускается код в initialization. LibraryProc тоже не запускается. Как и ожидалось.

Кстати, по сабжу я получил ответ в borland.public.delphi.language.delphi.win32 .


Palladin   (2004-12-31 00:01:00) [2]

Ну? Видишь, ты сам раскопал суть вопроса. Все ты так делаешь. Не бойся экспериментировать.

PS. Я ошибся в выводах, когда результаты нескольких вызовов LoadLibrary в одном и том же хостприложении обобщил как для разных хостприложений. Лень было несколько проектов создавать только ради ответа на один вопрос. :)


GuAV   (2004-12-30 13:03:00) [3]

2 VMcL ©

спасибо. хотя у меня этой ошибки не было.
дело в том что я привёл не свой код, а пример из статьи по хукам.

2 Palladin ©

Провёл собственные эксперименты..

library mydll;

{$IMAGEBASE $24000000}

uses
 Windows,
 Messages,
 SysUtils,
 Unit1 in 'Unit1.pas';

procedure LibraryProc(Reason: Integer);
begin
 case Reason of
   DLL_PROCESS_ATTACH: ShowMessage('ATTACH');
   DLL_PROCESS_DETACH: ShowMessage('DETACH');
 end;
end;

exports
 someproc;

begin
 ShowMessage(IntToHex(SysInit.HInstance, 8));
 ShowMessage('BEGIN');
 DllProc := LibraryProc;
 LibraryProc(DLL_PROCESS_ATTACH);
end.

--------------------------------------------

unit Unit1

interface

uses Windows, Messages;

procedure ShowMessage(s: string);

implementation

procedure ShowMessage(s: string);
begin
 MessageBox(0, PChar(s), 0, 0);
end;

initialization
 ShowMessage('INIT');
finalization
 ShowMessage('FINALIZE');
end.

==========================================

Создал несколько проектов с таким кодом

procedure TForm1.Button1Click(Sender: TObject);
begin
 Tag := LoadLibrary('hookdll.dll');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 FreeLibrary(Tag);
end;

всегда вызываются INIT - BEGIN - ATTACH при LoadLibrary и DETACH - FINALIZE при FreeLibrary.
Я что-то делаю не так ?


VMcL   (2004-12-30 07:38:00) [4]

> procedure DLLEntryPoint(dwReason: DWord); stdcall;

Кхм...
procedure DLLEntryPoint(dwReason: DWord); register;


Palladin   (2004-12-30 01:44:00) [5]

В общем то все увидел, что бы поразмышлять и поэкспериментировать.
В первый раз нужно вызвать в ручную. Все ты делаешь верно. Незакрытых дескрипторов не будет.


GuAV   (2004-12-30 01:07:00) [6]


> Во первых. Где это в справке Delphi написано про
> "вручную"?


DLLProc + F1
смотрю Note


> Во вторых. Читай справку которую я тебе указал. Ты не
> туда смотришь.


DllEntryPoint - нобязательная входная точка для DLL. Если она есть то вызывается когда процесс/поток создан/завершен или LoadLibraty/FreeLibrary.

DLL_PROCESS_ATTACH
Указывает что DLL присоединяется к адресному протранству процесса.
При начальной загрузке процесса или после вызова LoadLibrary ОС сканирует список DLL для процесса.
Для тех DLL для которых не был сделан вызов с DLL_PROCESS_ATTACH он делается. Вызов делается в контексте потока, который привёл к изменению адресного процесса.

Что ещё я не увидел ??


Palladin   (2004-12-30 00:51:00) [7]


> вручную ?

Во первых. Где это в справке Delphi написано про "вручную"? Во вторых. Читай справку которую я тебе указал. Ты не туда смотришь.


GuAV   (2004-12-30 00:24:00) [8]

Palladin ©   (30.12.04 0:18) [14]

Это сомений не вызывает. Так всё-таки ошибка в справке Delphi по DllProc, что DLL_PROCESS_ATTACH вызывается только из инициализации Dll вручную ?

и будет ли утечка хендла MMFHandle из-за неоднократного вызова OpenGlobalData ?


Palladin   (2004-12-30 00:18:00) [9]

Количество вызовов DllEntryPoint с DLL_PROCESS_DETACH будет соответствовать количеству вызовов с DLL_PROCESS_ATTACH.


GuAV   (2004-12-30 00:04:00) [10]

Прочита справку я понял, что
DllEntryPoint( ..., DLL_PROCESS_ATTACH, ... ) будет вызвано, когда dll будет присоединена к адресному пространству процесса. Причём если dll уже загружена в АП процесса, повторная попытка загрузить её не вызовет DllEntryPoint( ..., DLL_PROCESS_ATTACH, ... ).

в справке по Delphi написано
"DLL_PROCESS_ATTACH is passed to the procedure only if the DLL’s initialization code calls the procedure and specifies DLL_PROCESS_ATTACH as a parameter"

По поводу примера в [7] - не приводит ли более чем однократный вызов OpenGlobalData к утечке хендла в переменной MMFHandle ?


Palladin   (2004-12-29 23:46:00) [11]


> Значит и DLLEntryPoint(DLL_PROCESS_ATTACH) вызовется только
> один раз, т.к.

В ручную ты сделаешь только один вызов. Все остальные вызовы делать будет система.
Сказал же, читай справку WinAPI\Index\DllEntryPoint.


GuAV   (2004-12-29 23:41:00) [12]


> DLLProc назначится только один раз

Значит и DLLEntryPoint(DLL_PROCESS_ATTACH) вызовется только один раз, т.к.

DLL_PROCESS_ATTACH is passed to the procedure only if the DLL’s initialization code calls the procedure and specifies DLL_PROCESS_ATTACH as a parameter.

Тогда чем отличаются initialization у юнита и initialization у библиотеки в этом случае ?


Palladin   (2004-12-29 23:27:00) [13]

DLLProc назначится только один раз, DLLEntryPoint будет вызыватся так как описано в справки WinAPI.


GuAV   (2004-12-29 23:12:00) [14]

То есть, могут быть несколько вызовов
DllEntryPoint( .. DLL_PROCESS_ATTACH .. ), но после каждого обязательно будет вызов DllEntryPoint( .. DLL_PROCESS_DETACH .. ) ?


Palladin   (2004-12-29 23:02:00) [15]

Он правильный, но то ли ты от него ожидаешь, это другой вопрос.


GuAV   (2004-12-29 22:55:00) [16]


> Он инициализируется лишь раз. Финализируется точно
> столько же

А begin...end из .dpr библиотеке - может выполнится больше одного раза ?

Т.е. код



procedure CloseGlobalData();
begin
 UnmapViewOfFile(GlobalData);
 CloseHandle(MMFHandle);
end;

procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
 case dwReason of
   DLL_PROCESS_ATTACH: OpenGlobalData;
   DLL_PROCESS_DETACH: CloseGlobalData;
 end;
end;

begin
 DLLProc:= @DLLEntryPoint;
 DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


- неправилный ?

ps: Извините за тупость...


Palladin   (2004-12-29 22:47:00) [17]

Он инициализируется лишь раз. Финализируется точно столько же.


GuAV   (2004-12-29 22:44:00) [18]

Palladin ©   (29.12.04 22:34) [4]

То есть юнит не всегда инициализируется, когда выполняется begin...end в библиотеке ?


Palladin   (2004-12-29 22:34:00) [19]

не путай initialization у юнита и initialization у библиотеки!


GuAV   (2004-12-29 22:33:00) [20]

Т.е.

DLL_PROCESS_ATTACH is passed to the procedure onlyif the DLL’s initialization code calls the procedure and specifies DLL_PROCESS_ATTACH as a parameter

, но при этом финализация выполняется

> лишь при полной выгрузке библиотеки из памяти

?

Т.е. инициализация может вызыватся чаще чем финализация ? или что я не понимаю ?


Страницы:   1 2

Наверх

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