Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Вниз

Dll, dll, dll....   Найти похожие ветки 

 
Alive ©   (2004-07-08 12:35) [0]

Привет всем!

В свой DLL-ке я замещаю процедуру DllProc своей. Скажите мне, пожалуйста, почему не вызывается DLLProc с "ризоном" DLL_PROCESS_DETACH при явной выгрузке моей библиотеки из другой программы через FreeLibrary (Естественно я заранее ее туда "динамически" загрузил).
Какие идеи, мб кто-нибудь уже занимался этим сабжем? Как вообще определить, что моя DLL выгружается из адресного пространства другого процесса, не используя DllProc?


 
Digitman ©   (2004-07-08 12:47) [1]


> Alive ©   (08.07.04 12:35)  


быть того не может

покажи код


 
bar   (2004-07-08 15:23) [2]

>>Alive ©   (08.07.04 12:35)  
Я делаю примерно та и все работает.
....
procedure DLLEntryPoint(dwReason: DWord); stdcall;
begin
   case dwReason of
       DLL_PROCESS_ATTACH: OpenGlobalData;
       DLL_PROCESS_DETACH: CloseGlobalData;
   end;
end;

exports ...;

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

>>Как вообще определить, что моя DLL выгружается из адресного пространства другого процесса, не используя DllProc?

1)TaskManager+ TaskManagerEx
2)Попробовать переименовать файл дллки (ежели занят, то не получится).
3)Использовать спец. проги для вывода инфы о процессах и т.п. гдето слышал о такой хорошей ,но не помню. Поищи в инете.


 
bar   (2004-07-08 15:45) [3]

Получение списка DLL загруженных приложением  
http://delphiworld.narod.ru/base/get_loaded_dll_list.html


 
Digitman ©   (2004-07-08 16:09) [4]

убери stdcall


 
Alive ©   (2004-07-09 07:28) [5]

......

procedure DLLEntryPoint(dwReason: DWORD); stdcall;
begin
 case dwReason Of
   DLL_PROCESS_ATTACH :
     begin
       MessageBox(0, PChar("DLL_PROCESS_ATTACH"), PChar("DLL"), MB_TOPMOST);
     end;
   DLL_PROCESS_DETACH:
     begin
       MessageBox(0, PChar("DLL_PROCESS_DETACH"), PChar("DLL"), MB_TOPMOST);
     end
 end;
end;

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

Вот код, на ATTACH работает, при загрузке, а при выгрузке нет!


 
Alive ©   (2004-07-09 07:33) [6]


> 1)TaskManager+ TaskManagerEx
> 2)Попробовать переименовать файл дллки (ежели занят, то
> не получится).
> 3)Использовать спец. проги для вывода инфы о процессах и
> т.п. гдето слышал о такой хорошей ,но не помню. Поищи в
> инете.

Не то! Мне нужно вызвать определенную процедуру в моей длл-ке, когда она будет выгружаться...

И вообще: если DLL подгружена в разные процессы, то DLL_PROCESS_DETACH будет вызываться всегда, когда хотя бы один процесс "освободит" DLL, или только когда необходимость в DLL отпадет совсем, т.е. когда она не будет загружена ни одним процессом? Понимаю, что первый вариант, так SDK написано...


 
Digitman ©   (2004-07-09 08:25) [7]


> Alive ©   (09.07.04 07:28) [5]


убери stdcall !!


 
bar   (2004-07-09 10:24) [8]

>>Alive ©
DLL_PROCESS_ATTACH = 1; // Программа подключается к DLL
DLL_THREAD_ATTACH = 2;  // Поток программы подключается к DLL
DLL_THREAD_DETACH = 3;  // Поток "оставляет" DLL
DLL_PROCESS_DETACH = 0; // Exe "отсоединяется" от DLL
подробней см
http://delphiworld.narod.ru/base/threads_and_dll.html


 
Digitman ©   (2004-07-09 10:32) [9]


> bar   (09.07.04 10:24) [8]


> DLL_THREAD_ATTACH = 2;  // Поток программы подключается к DLL
> DLL_THREAD_DETACH = 3;  // Поток "оставляет" DLL


неверно

верно так :
DLL_THREAD_ATTACH = 2;  // В контексте тек.процесса стартован новый трэд
DLL_THREAD_DETACH = 3;  // Некий трэд тек.процесса коррекно завершен

цитата из справки :

DLL_THREAD_ATTACH
Indicates that the current process is creating a new thread.
..
DLL_THREAD_DETACH
Indicates that a thread is exiting cleanly.


 
bar   (2004-07-09 10:39) [10]

>>Digitman ©   (09.07.04 10:32) [9]
Цитировал http://delphiworld.narod.ru/base/threads_and_dll.html там так. Сам проверял только DLL_PROCESS_ATTACH и DLL_PROCESS_DETACH


 
Digitman ©   (2004-07-09 10:50) [11]


> bar   (09.07.04 10:39) [10]


цитировать желательно первоисточники, а не чьи-то досужие домыслы..
описание этой логики у Борланда в станд.справке с точностью до литеры совпададает с соотв.описанием в MSDN .. надеюсь, мануалы от Майкрософт можно считать первоисточником ?


> Сам проверял только DLL_PROCESS_ATTACH и DLL_PROCESS_DETACH


это - из другой оперы
DLL_PROCESS_ATTACH будет передан при первом (!) явном или неявном вызове LoadLibrary, ВНЕ зависимости от того, какой трэд процесса выполнил этот вызов


 
KosilkA ©   (2004-07-09 10:51) [12]

борланд советует исправить файл system.pas :
http://community.borland.com/article/0,1410,27753,00.html
Правда там сказано что это касается 5 Delphi, но в 6-й тоже есть такой же фрагмент кода ...... Единственное чего я не понял - как создать новый файл System.dcu ? Копировал файл system.pas в папку проекта , правил его , из проекта его видно , но толку никакого,видимо нужен перекомпиленный dcu


 
Digitman ©   (2004-07-09 11:12) [13]

вот так это выглядит в v5 build 6.18 UpdatePack 1

procedure       _StartLib;
asm
       { ->    EAX InitTable   }
       {       EDX Module      }
       {       ECX InitTLS     }
       {       [ESP+4] DllProc }
       {       [EBP+8] HInst   }
       {       [EBP+12] Reason }
...
@@noTLSproc:

       { Call any DllProc }

       MOV     EDX,[ESP+4]
       TEST    EDX,EDX
       JE      @@noDllProc
       MOV     EAX,[EBP+12]
       CALL    EDX

у меня все замечательно работает


 
bar   (2004-07-09 11:16) [14]

>>Digitman ©   (09.07.04 10:50) [11]
Да, да, да верно говорите батенька. Но первоисточники на англицком а я его толко учу (пытаюсь).


 
KosilkA ©   (2004-07-09 11:20) [15]

TO
> Digitman ©   (09.07.04 11:12) [13]


у меня все именно так же ,но не работает ....правда делфа шестая.  Можешь написать работающий пример/кусочек кода ,если не трудно ?


 
Digitman ©   (2004-07-09 11:29) [16]


> bar   (09.07.04 11:16) [14]



> первоисточники на англицком


сожалею... зато очепятки и явная отсебячина в несуразных порой русскоязычных переводах отсутствуют


а я его толко учу (пытаюсь).


успехов тебе


> KosilkA ©   (09.07.04 11:20) [15]


пример чего ?

вот он, пример, уже приведен выше :

procedure DLLEntryPoint(dwReason: DWord); // stdcall; никаких СТДкОлов !!! читать справку до посинения !

begin
  case dwReason of
      DLL_PROCESS_ATTACH: ...;
      DLL_PROCESS_DETACH: ...;
      DLL_THREAD_ATTACH: ...;
      DLL_THREAD_DETACH: ...;
  end;
end;
..
begin
  DLLProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.


 
KosilkA ©   (2004-07-09 12:34) [17]

TO Digitman: так именно так же я и сделал. (никаких СТДколлов , я это запомнил хорошо =))).

выдержка из хелпа:
DLL_PROCESS_DETACH Indicates that the library is detaching from the address space of the calling process as a result of a clean exit or a call to FreeLibrary or (dlclose on Linux).

Загружаю длл так:
var dll:cardinal;
.......
dll:=loadlibrary("dll.dll");
выгружаю:
freelibrary(dll);

в дллке:

procedure DLLEntryPoint(dwReason: DWord);
begin
 case dwReason of
     DLL_PROCESS_ATTACH:messagebox(0,"DLL_PROCESS_ATTACH","",0);
     DLL_PROCESS_DETACH: messagebox(0,"DLL_PROCESS_DETACH","",0);
     DLL_THREAD_ATTACH: messagebox(0,"DLL_THREAD_ATTACH","",0);
     DLL_THREAD_DETACH: messagebox(0,"DLL_THREAD_DETACH","",0);
end;
end;

begin
fname:=allocMem(MAX_PATH+1);
GetModuleFileName(GetModuleHandle(nil),fname,MAX_PATH+1);
messagebox(0,fname,"",0);
DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end;
---------------------------------
DLL_PROCESS_DETACH не срабатывает.


 
Digitman ©   (2004-07-09 12:50) [18]


> KosilkA ©   (09.07.04 12:34) [17]


у меня твой код прекрасно работает - я получаю сообщения и о DLL_PROCESS_ATTACH и о DLL_PROCESS_DETACH


 
KosilkA ©   (2004-07-09 13:07) [19]


> Digitman ©   (09.07.04 12:50) [18]

может действительно в модуле System проблема ,как сказано на сайте борланда? Я сейчас специально создал голый проект с кнопкой (freeelibrary) на форме и с дллкой , с одной лишь функцией dllpoint ... ну не ловит она когда ее выгружают , хоть ты тресни (((((


 
Digitman ©   (2004-07-09 15:18) [20]


> KosilkA ©   (09.07.04 13:07) [19]


про Д6 ничего сказать не могу
я упомянул уже о версии и билде, которыми пользуюсь


 
Alive ©   (2004-07-09 16:07) [21]


> bar   (09.07.04 10:24) [8]

Да что мне туда смотреть, знаю я что, да когда... (SDK)

Всем спасибо, попробую переписать system.pas %)


 
Lin7   (2004-07-09 16:18) [22]

Это баг делфы версий 5-7.

Я в своё время поборол так: добавил к проекту dll модуль pas и в его секции initianization прописал свой код DLL_PROCESS_ATTACH, а в finalization соответственно DLL_PROCESS_DETACH. Это работало в 6 и 7 версиях.
system.pas при этом править не надо.
Код
begin
  DLLProc := @DLLEntryPoint;
  DLLEntryPoint(DLL_PROCESS_ATTACH);
end.
тоже не нужен.
Как обрабатывать DLL_THREAD_ATTACH/DLL_THREAD_DETACH я не знаю -не было необходимости.

Удачи в нелёгком деле.


 
Alive ©   (2004-07-09 17:16) [23]

Действительно: а как перекомпилить RTL?

В Delphi 6 точно баг. В system.pas (от Delphi 7) код исправлен, соответсвенно и моя DLL теперь работает (откомпиленная в 7-ом).
Но уж больно люблю 6-ой (не спрашивайте за что)!

Так как: а как перекомпилить RTL?


 
KosilkA ©   (2004-07-09 19:17) [24]


> Alive ©   (09.07.04 17:16) [23]

Официально было сказано что нужно сделать :

Due to RTL changes, the DLLProc was not being called appropriately. This change will fix the change that you may have noticed. Once you have completed the change, you will need to recompile the RTL and copy the new System.dcu into your project directory. Your project will use the newly created System.dcu with the fix included. In System.pas, navigate down to this method @@skipTLSproc.

То есть - подредактировать system.pas , перекомпилировать RTL , а после этого зачем то (?) скопировать свеженький файл system.dcu в папку своего проекта.. Гы...Ну ладно. Я наверное дурак ,но как перекомпилить rtl я так и не понял .Пробовал открыть dclusr.dpk (в него входит rtl.dcp) , открываю этот rtl - system.pas там не наблюдается , но все равно на всяк случай компиллирую - толку ноль , system.dcu осатется без изменений как того и стоило ожидать . Так же и перекомпилляция dclusr не привносит никаких изменений.


 
Alive ©   (2004-07-10 08:28) [25]


> Lin7   (09.07.04 16:18) [22]

Это конечно хорошо, и в правду так все работает, но не красиво.

> KosilkA ©   (09.07.04 19:17) [24]
>
> > Alive ©   (09.07.04 17:16) [23]
>
> Официально было сказано что нужно сделать :


Я это и пытлся сделать, но почему-то не выходит... Я еще пробовал удалить system.dcu, чтобы заставить Delphi перекомпилить system.pas, но потом стало одумался: чтобы перекомплить хотя бы тот же самый system.pas, нужен же уже откомпиленный system.pas. С паками я тоже парился... Что за фигня. В Borland"е все такие умные что ли?


 
KosilkA ©   (2004-07-10 10:03) [26]

хм..а вот тут вот речь идет о пятой версии дельфи http://delphi.olympus.ru/dk/treasury/addrefarray.htm  
Оказывается что для компиляции dcu файлов требуется турбоассембллер (tasm32.exe) ...да и то через задницу, все равно как там сказано, после этого какие то грабли с vcl вылазят... И как панацея от всех бед приводится пример исправления неправильной процедуры в памяти программы в рантайме =))


 
Wasp   (2004-07-11 01:34) [27]

Я сам подобным заморачивался несколько дней, а потом прочитал, что в Delphi 6 и 5 есть ошибка. Компильнул в седьмой - работает!
так что советую поставить delphi 7 или пропатчить system.pas или
system.dcu.


 
Alive ©   (2004-07-11 09:11) [28]

Вух, откомпилил system.pas. Теперь все работает. На пакеты наплевать, их все равно не использую...



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.033 c
6-1087727849
korvin
2004-06-20 14:37
2004.08.22
Кто меня юзает?


1-1091646763
Black-Grin
2004-08-04 23:12
2004.08.22
Combobox - редактирование


4-1088894848
Spy.RU
2004-07-04 02:47
2004.08.22
Доступ к строке инициализации модема


6-1086782787
Anton.
2004-06-09 16:06
2004.08.22
Как получить сообщение от TCPServera?


14-1091498196
Думкин
2004-08-03 05:56
2004.08.22
С днем рождения! 3 августа





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский