![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Dll и TThread [D5, D7, WinXP]
dms_main © (2004-10-29 10:02:00)
Страницы: < 1 2 3 4 5 6 7 8 9 >
Уважаемые мастера, обнаружил такой глюк.
Есть класс на основе стандартного Tthread,
креатится так:
constructor tmythread.create;
begin
inherited create(false);
end;
Проблема в том , что в dll невызывается execute, хотя в console Application все работало замечательно.
Как лечить?
dms_main (2004-10-29 16:31:00) [61]Digitman ©
сорри забыл дописать перед пелодом ctrl+alt+m
Reindeer Moss Eater (2004-10-29 16:31:00) [62]Добрый дядька © (29.10.04 16:30) [105]
Это не объясняет феномен невызова Execute
Добрый дядька (2004-10-29 16:30:00) [63]В случае, если нужно дождаться завершения потока, то используется FreeOnTerminate := True,
затем
WaitFor
Free
Это из-за особенностей реализации TThread
Reindeer Moss Eater (2004-10-29 16:30:00) [64]По условиям задачи разве не это нужно?
не это нужно по условиям задачи
Reindeer Moss Eater (2004-10-29 16:29:00) [65]Добрый дядька © (29.10.04 16:28) [101]
Это не объясняет феномен невызова Execute
Добрый дядька (2004-10-29 16:29:00) [66]>Reindeer Moss Eater © (29.10.04 16:27)
Если делать это в одном потоке.
По условиям задачи разве не это нужно?
Добрый дядька (2004-10-29 16:28:00) [67]Вторая ошибка потому, что
FreeOnTerminate:=true;
Не может использоваться с
thread.WaitFor;
Reindeer Moss Eater (2004-10-29 16:27:00) [68]Добрый дядька © (29.10.04 16:20) [94]
Все прекрасно работает как в таком виде:
Если делать это в одном потоке.
dms_main (2004-10-29 16:26:00) [69]
>
> {$R *.RES}
> var
> thread:TMyThread;
> begin
> thread:=TMyThread.create(2,2);
> thread.WaitFor;
> end.
>
> Это вторая.
а если мне надо дождаться его завершения?
Добрый дядька (2004-10-29 16:25:00) [70]А вот ошибка в твоем коде:
constructor TMyThread.create(a0,b0:integer);
begin
inherited create(false);
a:=a0;
b:=b0;
FreeOnTerminate:=true;
end;
Это первая.
{$R *.RES}
var
thread:TMyThread;
begin
thread:=TMyThread.create(2,2);
thread.WaitFor;
end.
Это вторая.
dms_main (2004-10-29 16:25:00) [71]I>
> Все прекрасно работает как в таком виде:
как было так и есть...<
Добрый дядька (2004-10-29 16:21:00) [72]Сорри, строка ResumeThreadв конструкторе не нужна.
Digitman (2004-10-29 16:21:00) [73]
> dms_main © (29.10.04 16:03) [92]
в Д5 в настройках Host Application нет никаких Reload Symbol Table
это раз.
второе.
ты стартовал отладку ДЛЛ, поймал брейкпойнт на строчке
thread:=TMyThread.create(2,2);
почему не прошел конструктор пошагово ?
ведь если BeginThread() выполнилась успешно, то признаков фактическогостарта трэда более чем достаточно !
это и ненулевой ThreadId и ненулевой Handle ... То что Handle ненулевой - это уже гарантировано, иначе WaitFor немедленно возвратил бы управление, чего, как ты говоришь, не наблюдается у тебя .. .
а если так, то рано или поздно процедура Execute обязана была бы получить управление ! Ведь поточная ф-ция успешно стартовала !
Добрый дядька (2004-10-29 16:20:00) [74]Все прекрасно работает как в таком виде:
library ThrDll;
uses
Classes,
windows;
type
TMyThread=class(TThread)
FX: String;
protected
procedure Execute; override;
public
constructor Create(const X: String);
end;
{ MyThread }
constructor TMyThread.Create(const X: String);
begin
inherited Create(True);
FX := X;
FreeOnTerminate := True;
Resume;
ResumeThread(Self.Handle);
end;
procedure TMyThread.Execute;
var
i: Integer;
begin
for i := 0 to 10 do
begin
Sleep(200);
Write(FX+#13#10);
end;
Terminate;
end;
procedure DllMain(fdwReason:DWORD);
begin
case fdwReason of
DLL_THREAD_ATTACH: ;
DLL_THREAD_DETACH: ;
DLL_PROCESS_ATTACH:
begin
TMyThread.Create('Hehe');
end;
DLL_PROCESS_DETACH:
begin
end;
end;
end;
begin
DllProc:=@DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.
Вызывающий код:
program test;
{$APPTYPE CONSOLE}
uses
Windows;
begin
LoadLibrary('ThrDll.dll');
ReadLn;
end.
так и если убрать DLLMain, а просто вставить в DLL всекцию после begin
TMyThread.CrReate('Hehe');
dms_main (2004-10-29 16:18:00) [75]проверить кстати можно еще проще :
procedure TMyThread.execute;
var
t:TstringList;
begin
c:=a*b;
t:=TStringList.Create;
t.Add('Result = '+inttostr(c));
t.SaveToFile('c:\result.nfo');
t.Free;
end;
в "Экспортном" варианте файл создается, в Loadlibrary - не создается.
dms_main (2004-10-29 16:03:00) [76]Run>Parameters>Host Application>F9
"MyLib">Reload Symbol Table
Digitman (2004-10-29 16:00:00) [77]
> без экспорта
да экспорт-то тут причем ?!
хоть он есть, хоть его нет - ну никак это не влияет на сабж !
> не веришь
представь себе - не верю !
и даже проверять не буду ..
и глубоко фиолетово к тому же, КАК грузится твоя ДЛЛ - статически или динамически ..
давай-ка рассказывай, как ты "ловишь" брейкпойнты ..
Reindeer Moss Eater (2004-10-29 16:00:00) [78]креатит но execute не вызывает....
Это потому что хэллоуин на носу.
Подожди до понедельника, будет тебе execute
dms_main (2004-10-29 15:59:00) [79]
> Чё, еще раз?
> Ну давай еще один раз:
>
> Сто раз вызови LoadLibrary - код межу begin end выполнится
> ровно один раз.
спасибо - это я уже давно понял...... оно и вызывается 1 раз - креатит но execute не вызывает....
dms_main (2004-10-29 15:57:00) [80]
> ерунду не городи.
>
> ставь брейкпойнты на строчках
>
> c:=a*b;
>
> и
>
> thread:=TMyThread.create(2,2);
>
> и лови эти брейкпойнты !
>
> и попробуй только сказать, что ни один из них не "ловится"
именно это и говорю......
И вообще тема разговора именно эта!!!
не веришь - скомпиляй код (сообщение 67) - без экспорта и
через loadlibrary.....