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