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

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

Dll и TThread [D5, D7, WinXP]


Страницы:   1 2 3 4 5 6 7 8 9

dms_main ©   (2004-10-29 10:02:00) 

Уважаемые мастера, обнаружил такой глюк.
Есть класс на основе стандартного Tthread,
креатится так:

constructor tmythread.create;
begin
   inherited create(false);
end;

Проблема в том , что в dll невызывается execute, хотя в console Application все работало замечательно.
Как лечить?


dms_main   (2004-11-02 22:11:00) [1]

Господа! Все оказалось намного проще....
Execute выполняется после begin...end. библиотеки, правда есть одно но - но это не важно.
Решается так :
Создаем еще один класс потока,
create его ставим в begin...end. библиотеки, на его execute забиваем create того кода что был в begin ... end. библиотеки -
и все у нас работает прекрасно.
Спасибо всем кто принял участие в решении вопроса.....


DiamondShark   (2004-11-01 14:28:00) [2]


> Reindeer Moss Eater ©   (01.11.04 13:50) [164]
> А еще он говорит, что в консольном приложении все нормально.
> И никакой waitfor ему не помеха.

А мы на слово никому не верим.

Проблема воспроизведена, причина описана, пути решения намечены.
Ждём-с реакции автора...


Digitman   (2004-11-01 13:58:00) [3]

что-то подустал я тут из пустого в порожнее переливать ..

автор давно уже ни мычит ни телится


Reindeer Moss Eater   (2004-11-01 13:50:00) [4]

Тем не менее, его код на LoadLibrary именно зависает.

А еще он говорит, что в консольном приложении все нормально.
И никакой waitfor ему не помеха.


DiamondShark   (2004-11-01 13:40:00) [5]


> Digitman ©   (01.11.04 13:32) [162]

Мало ли что автор не говорит, он свой реальный код тоже долго не говорил.
Тем не менее, его код на LoadLibrary именно зависает.


Digitman   (2004-11-01 13:32:00) [6]


> DiamondShark ©   (01.11.04 13:04) [158]
> Не-а. У него там WaitFor стоит.


WaitFor в таком контексте [см. 154] д.б. бы вызвать дэдлок, однако автор ничего не говорит на тему якобы "зависания" приложения, вызывающего ДЛЛ по LoadLibrary.


DiamondShark   (2004-11-01 13:24:00) [7]

Да нет там никаких проблем икспи-отладчик...


Юрий Зотов   (2004-11-01 13:22:00) [8]

Всю ветку читать не стал - слишком длинная. Поэтому просто скажу, в чем тут, похоже, дело и сорри, если повторю кого-то или скажу "не в кассу".

Проблема XP-DLL-отладчик известная (хоть в однопоточном, хоть в многопоточном приложении). По какой-то причине отладчик не подгружает отладочную символьную информацию из DLL и поэтому брейкпойнты в DLL не срабатывают (хотя код работает). Лечится это либо установкой эксперта IDE (встречал в сети, но где - не помню), либо так.

1. В DLL сразу после главного begin пишем любой MesssageBox  -что угодно, лишь бы тормознуть программу.

2. Когда этот MessageBox появится, переключаемся в Delphi, жмем Ctrl-Alt-M, в появившемся окне (слева внизу) находим свою DLL, жмакаем по ней правой кнопкой мыши и выбираем Reload Symbol Table. Если все прошло ОК, то справа увидим, что отладочная информация подгрузилась.

3. В MessageBox жмем OK - теперь брейкпойнты должны работать.


DiamondShark   (2004-11-01 13:14:00) [9]

Объясняю.

Вызываем LoadLidrary, LoadLidrary не возвращается, пока не отработает DLL entry point.
В DLL entry point создаётся поток, который будет подвешен, пока не завершится DLL entry point.
К контексте DLL entry point вызывается поток.WaitFor, которая не вернётся, пока не закончится поток, который не запустится пока не закончится DLL entry point, которая не закончится пока не вернётся WaitFor... в доме который построил Джек.

Если убрать WaitFor, то поток начнёт работь сразу, как вернётся DLL entry point. Тут, правда автором заботливо подложены другие грабли в виде FreeLibrary сразу после LoadLibrary.


DiamondShark   (2004-11-01 13:04:00) [10]


> Reindeer Moss Eater ©   (01.11.04 12:57) [156]

Это ты к чему?


> Digitman ©   (01.11.04 12:57) [157]
> ну и что ? рано или поздно ВР должна сработать !

Не-а. У него там WaitFor стоит.


Digitman   (2004-11-01 12:57:00) [11]


> Reindeer Moss Eater ©   (01.11.04 12:43) [155]


я ОДНОГО не понял - автор утверждает, что ВР в теле Execute он ВООБЩЕ не ловит в ходе самого первого обращения к ДЛЛ ... хотя тело конструктора хотя бы однократно получает управление ...

этого быть не может - рано или поздно поточная ф-ция все равно стартует


> DiamondShark ©   (01.11.04 12:41) [154]


ну и что ? рано или поздно ВР должна сработать !


Reindeer Moss Eater   (2004-11-01 12:57:00) [12]

DiamondShark ©

Любите источник знаний целиком и до конца.
Все это касается статического импорта библиотеки.
Если импорт динамический, то вторичному потоку ничто не помешает ни выполняться, ни самому грузить dll первее главного треда


Reindeer Moss Eater   (2004-11-01 12:43:00) [13]

Он (автор) хочет, что бы бегин/енд выполнялся при LoadLibrary из любого потока хост приложения.

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


DiamondShark   (2004-11-01 12:41:00) [14]

Балин...
Любите хелп -- источник знаний:

During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is donefor the process.


Digitman   (2004-11-01 11:50:00) [15]


> Reindeer Moss Eater ©   (29.10.04 17:41) [149]


DLL_THREAD_ATTACH здесь к делу никоим образом не относится

как только любой трэд процесса в самый первый раз будет грузить ДЛЛ (явно или неявно), системой будет вызвана DllEntryPoint(DLL_PROCESS_ATTACH), что в конечном счете должно привести к передаче управления в блок begin..end библиотеки, где у автора вызывается конструктор TMyThread.Create (он и вызывается в действительности - автор это подтверждает) .. если в ходе работы конструктора не возникло исключений, то поточная ф-ция обязана стартовать и вызвать при этом Execute, и брейкпойнт в самом начале тела Execute ну просто обязан быть пойманным отладчиком ..


Reindeer Moss Eater   (2004-11-01 10:40:00) [16]

Что бы "работало" без экспорта

library lib;

uses Windows;
{$R *.res}

procedure DllProcedure(AReason : integer);
begin
case AReason of
 DLL_PROCESS_ATTACH,
 DLL_THREAD_ATTACH  : begin
                       //Создание экземпляров TThread
                       ....  
                      end;
 DLL_PROCESS_DETACH :;
 DLL_THREAD_DETACH  :;
end;
end;

begin
DllProc := DllProcedure;
DllProc(DLL_PROCESS_ATTACH);
end.


Defunct   (2004-10-29 19:07:00) [17]

Ну и развели..

Надо было сказать:

> Лечиться это или нет - вот в чем вопрос.

Лечится только в военном госпитале.


Reindeer Moss Eater   (2004-10-29 17:52:00) [18]

И вообще не понятно, откуда берутся параметры для конструктора того потока, если его запуск заточен под автоматическое выполнение кода между begin/end библиотеки при простой загрузке библиотеки.

Получается, что они вообще хардкодед.


Reindeer Moss Eater   (2004-10-29 17:41:00) [19]

с какой стати отладчик автоматом загрузит ДЛЛ, если она в хост-приложении грузится искл-но динамически ?
Динамически. Да.
Но не из единственного потока.

какая разница, откуда будет вызвана в дан.случае LoadLibrary - из основного или доп.трэда хост-процесса ?

Никакой разницы нет. Можно из основного, можно из вторичного.

Разница есть какой поток делает это первым в процессе.

Потому что у него код создания потока, создающего файлы привязан к блоку begin/end библиотеки.

А блок этот вызывается один раз за весть процесс сколько бы ни вызывали LoadLibrary в этом процессе.

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


Добрый дядька   (2004-10-29 17:37:00) [20]

>dms_main ©   (29.10.04 17:30)
WAitFor убери. Совсем.


Страницы:   1 2 3 4 5 6 7 8 9

Наверх

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