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