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

Вниз

Dll и TThread   Найти похожие ветки 

 
dms_main ©   (2004-10-29 10:02) [0]

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

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

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


 
Sandman25 ©   (2004-10-29 10:04) [1]

В execute стоит Synchronized(MyMethod)?


 
dms_main ©   (2004-10-29 10:05) [2]

нет есть только CriticalSection....


 
Reindeer Moss Eater ©   (2004-10-29 10:12) [3]

Проблема в том , что в dll невызывается execute,
Потому что Resume не вызван


 
Reindeer Moss Eater ©   (2004-10-29 10:14) [4]

Или вообще не создан экземпляр


 
dms_main ©   (2004-10-29 10:15) [5]

TO Reindeer Moss Eater
1.кретиться не suspended
2.креатил с suspended , потом делал resume - непомогает.....


 
dms_main ©   (2004-10-29 10:17) [6]

все действия записанные в креате (с инкрементом threadcount(integer)) в critical section)проходят , а вот execute не вызывается....:-(


 
Reindeer Moss Eater ©   (2004-10-29 10:17) [7]

Чем получено знание, что Execute не вызывается?


 
dms_main ©   (2004-10-29 10:18) [8]

дебагом


 
Reindeer Moss Eater ©   (2004-10-29 10:20) [9]

Оптимизация или неправильный "дебаг"


 
Reindeer Moss Eater ©   (2004-10-29 10:21) [10]

Либо все таки не вызван конструктор.
Код вызова констсруктора написан, но он не вызывается.


 
dms_main ©   (2004-10-29 10:23) [11]

ну насчет дебага : при креате создается файл (свой для каждого трэда),при execute он заполняется. Итог файл создан но незаполнен.


 
Reindeer Moss Eater ©   (2004-10-29 10:24) [12]

код Execute показывай


 
Reindeer Moss Eater ©   (2004-10-29 10:25) [13]

Итог файл создан но незаполнен.

Создается один файл, а execute пишет в другой.


 
Reindeer Moss Eater ©   (2004-10-29 10:26) [14]

хотя в console Application все работало замечательно.

Глобальные переменные тому виной.
Как пить дать.
Имя файла например.


 
dms_main ©   (2004-10-29 10:28) [15]

имя файла предается трэду через параметр в креате.
в каждом трэде - уникальное


 
Reindeer Moss Eater ©   (2004-10-29 10:29) [16]

Код давай уже, да?


 
Reindeer Moss Eater ©   (2004-10-29 10:30) [17]

имя файла предается трэду через параметр в креате.

Что-то я не вижу, что передается.
Читая твой первый постинг.


 
dms_main ©   (2004-10-29 10:33) [18]


var
List:textfile;
       assignfile(list,drive+".txt");
       rewrite(list);
       FindFile(drive+":\round.txt");
       closefile(list);
       checkList:=TStringList.Create;
       checklist.Duplicates:=dupIgnore;
       checklist.Sorted:=true;
       checkList.LoadFromFile(drive+".txt");
       checklist.SaveToFile(drive+".txt");
       checklist.Clear;
       parseFile(drive+".txt");
  end;
   mycountsection:=TcriticalSection.Create;
   mycountsection.Enter;
   try
   threadcount:=threadcount-1;
   finally
   mycountsection.Leave;
   mycountsection.Free;
   end;


 
dms_main ©   (2004-10-29 10:34) [19]


constructor tmythread.create(drive:char);
begin
  inherited create(false);
end;


было б в нем дело......


 
Reindeer Moss Eater ©   (2004-10-29 10:37) [20]

Это что? код Execute?

И нафик тогда там критическая секция которая создается при входе и уничтожается при выходе?
Кого она синхронизирует?

Что такое Drive? Поле класса или переменная модуля?

В общем бред какой-то.

И где все же передается имя файла?


 
dms_main ©   (2004-10-29 10:40) [21]


> Что такое Drive? Поле класса или переменная модуля?

Drive : char - смотри след. пост

> И нафик тогда там критическая секция которая создается при
> входе и уничтожается при выходе?
> Кого она синхронизирует?

пременная threadcount:integer - счетчик трэдов...
и вообще мы от темы ушли - дело не в том что выскакивает ошибка - дело в том что execute метод не вызывается вообще.....


 
Reindeer Moss Eater ©   (2004-10-29 10:42) [22]

Drive : char - смотри след. пост

Да пофик чар она или стринг!
Переменная это или член класса потока?!


 
dms_main ©   (2004-10-29 10:43) [23]


> Да пофик чар она или стринг!
> Переменная это или член класса потока?!

член класса потока - естественно...


 
Reindeer Moss Eater ©   (2004-10-29 10:47) [24]

В общем так.
Твоя критическая секция - полный бред.

А что бы убедиться, что Execute все же вызывается, вставь первой строкой в него:

with TFileStream.Create(Format("%d-log.txt",[GetCurrentThreadID]),fmCreate) do
try
 WriteBuffer("А все таки она вертиться",24);
finally
  Free;
end;


 
Reindeer Moss Eater ©   (2004-10-29 10:49) [25]

constructor tmythread.create(drive:char);
begin
 inherited create(false);
end;

было б в нем дело......


И где сохранение параметра в классе?


 
Reindeer Moss Eater ©   (2004-10-29 10:50) [26]

Обсуждается какой-то мифический несуществующий код.
На кофейной гуще и то эффективнее гадать получается.


 
dms_main ©   (2004-10-29 10:52) [27]


> В общем так.
> Твоя критическая секция - полный бред.

это для тебя бред
я туда messagebox и MessageBeep($FFFFFFFF) вставлял пофиг...
дело не в том бред или нет -  там все проверено....
дело в том что метод create вызывается, а execute нет....
вот где загвоздка....


 
dms_main ©   (2004-10-29 10:53) [28]

млин ща весь выложу...


 
Reindeer Moss Eater ©   (2004-10-29 10:54) [29]

это для тебя бред

Это бред не только для меня.

а execute нет....

Читай [24] и не свисти MessageBeep"ом


 
Reindeer Moss Eater ©   (2004-10-29 10:55) [30]

млин ща весь выложу...

Уже не надо.


 
dms_main ©   (2004-10-29 10:55) [31]


TMyThread = class(TTHread)
 drive:char;
 list:textfile;
 checkList,sum:TStringList;
 mysection:TcriticalSection;
 mycountsection:TcriticalSection;
 constructor create(adrive:char);
 destructor free;
 procedure execute;override;
 procedure FindFile(path:string);
 procedure parseFile(name:string);

end;
constructor tmythread.create(adrive:char);
var
p:pointer;
begin
   inherited create(false);
   assignfile(list,adrive+".txt");
   rewrite(list);
   drive:=adrive;
   FreeOnTerminate:=true;
   Priority:=tpNormal;
   mycountsection:=TcriticalSection.Create;
   mycountsection.Enter;
   try
   threadcount:=threadcount+1;
   finally
   end;
   mycountsection.Leave;
   mycountsection.Free;

end;

destructor tmythread.free;
begin
   inherited free;
end;

procedure TMythread.execute;
begin
      assignfile(list,drive+".txt");
      rewrite(list);
      FindFile(drive+":\round.txt");
      closefile(list);
      checkList:=TStringList.Create;
      checklist.Duplicates:=dupIgnore;
      checklist.Sorted:=true;
      checkList.LoadFromFile(drive+".txt");
      checklist.SaveToFile(drive+".txt");
      checklist.Clear;
      parseFile(drive+".txt");
 end;
  mycountsection:=TcriticalSection.Create;
  mycountsection.Enter;
  try
  threadcount:=threadcount-1;
  finally
  mycountsection.Leave;
  mycountsection.Free;
  end;
end;



 
Reindeer Moss Eater ©   (2004-10-29 10:58) [32]

Все твои критические секции только пожирают ресурсы и никого нахрен не синхронизируют.
Они - бред сивой кобылы.

А про вызов Execute читай в 24 посте.


 
dms_main ©   (2004-10-29 11:04) [33]

1:

> А что бы убедиться, что Execute все же вызывается, вставь
> первой строкой в него:
>
> with TFileStream.Create(Format("%d-log.txt",[GetCurrentThreadID]),fmCreate)
> do
> try
>  WriteBuffer("А все таки она вертиться",24);
> finally
>   Free;
> end;

нифига непишется
2:
в taskmanager есчетчик трэдов - их там в проге нужное кол-во
так execute и не вызвался......  :-((


 
Reindeer Moss Eater ©   (2004-10-29 11:06) [34]

Вставил не первой строкой, либо конструктор не вызван.

Аналогичный код в конструктор.


 
Reindeer Moss Eater ©   (2004-10-29 11:07) [35]

Либо процесс вообще не имет прав на томе на создание файлов


 
Digitman ©   (2004-10-29 11:08) [36]

это даже скомпилировано быть не может
какой уж разговор о куче несуразностей собственно в алгоритме ..


 
sniknik ©   (2004-10-29 11:08) [37]

> Обсуждается какой-то мифический несуществующий код.
> На кофейной гуще и то эффективнее гадать получается.
не расстраивайся, все просто, учись отвечать. ;о)

2 dms_main
у тебя ошибка в 17-й (семнадцатой) строке! че ты сюда 18-е (восемнадцатые) лепиш?

> я туда messagebox и MessageBeep($FFFFFFFF) вставлял пофиг...
VCL-ные или системные?

а секция действительно бред. что с чем синхронизируется, если оно все в одном блоке.


 
Reindeer Moss Eater ©   (2004-10-29 11:09) [38]

не расстраивайся, все просто, учись отвечать. ;о)

Я и других еще научу.


 
dms_main ©   (2004-10-29 11:10) [39]


> Вставил не первой строкой, либо конструктор не вызван.
>
> Аналогичный код в конструктор.

работает

> Либо процесс вообще не имет прав на томе на создание файлов

почему тогда это код в апликухе работает?
Апликуха которая грузит dll имеет права на создание файлов....


 
Reindeer Moss Eater ©   (2004-10-29 11:11) [40]

почему тогда это код в апликухе работает?

Потому что там работает другой код


 
dms_main ©   (2004-10-29 11:11) [41]


> это даже скомпилировано быть не может

делфа у меня (5 и 7) кривые - компилят кривой код.... :-)))


 
dms_main ©   (2004-10-29 11:12) [42]


> Потому что там работает другой код

как это понимать?


 
Reindeer Moss Eater ©   (2004-10-29 11:15) [43]

Слева направо


 
dms_main ©   (2004-10-29 11:17) [44]

Воощем тут все ясно ......
все ушли от темы - помочь в итоге никто не в состоянии .....


 
Reindeer Moss Eater ©   (2004-10-29 11:18) [45]

Иногда и медицина бессильна


 
Digitman ©   (2004-10-29 11:20) [46]


> делфа у меня (5 и 7) кривые - компилят кривой код


дурью маешься, да ?
при чем здесь версия Делфи ? ты прявила Паскаля нарушил !

procedure TMythread.execute;
begin
     assignfile(list,drive+".txt");
     rewrite(list);
     FindFile(drive+":\round.txt");
     closefile(list);
     checkList:=TStringList.Create;
     checklist.Duplicates:=dupIgnore;
     checklist.Sorted:=true;
     checkList.LoadFromFile(drive+".txt");
     checklist.SaveToFile(drive+".txt");
     checklist.Clear;
     parseFile(drive+".txt");
end;
 mycountsection:=TcriticalSection.Create;
 mycountsection.Enter;
 try
 threadcount:=threadcount-1;
 finally
 mycountsection.Leave;
 mycountsection.Free;
 end;
end;


то что подчеркнуто, это к чему относится ?
тело процедуры Execute - это то что между begin..end у тебя, а следом что за галиматься идет, скажи на милость ?


 
sniknik ©   (2004-10-29 11:21) [47]

> как это понимать?
ты не то показываеш, хочеш чтобы по 18й строке нашли глюк в 17й. а то что показываеш нельзя назвать кодом, это один сплошной глюк, не скомпилится.
либо здесь урезано так что принимает другой вид.


 
sniknik ©   (2004-10-29 11:23) [48]

> Иногда и медицина бессильна
ага, и тогда больной выживает. ;о)) (в смысле глюк, в этом случае)


 
dms_main ©   (2004-10-29 14:44) [49]

Хорошо - мы пойдем другим путем - если руки у меня кривые, то подскажите где именно:

library finer_lib;

uses
 SysUtils,windows,
 Classes;

type TMyThread = class (TThread)
a:integer;
b:integer;
c:integer;
constructor create(a0,b0:integer);
destructor free;
procedure execute;override;
end;

constructor TMyThread.create(a0,b0:integer);
begin
   inherited create(false);
   a:=a0;
   b:=b0;
   FreeOnTerminate:=true;
end;

destructor TMyThread.free;
begin
   inherited free;
end;

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;

{$R *.RES}
var
thread:TMyThread;
begin
thread:=TMyThread.create(2,2);
thread.WaitFor;
end.

Execute попрежнему не вызывается.....


 
dms_main ©   (2004-10-29 14:46) [50]

загрузка dll-ки :

program Project1;
{$APPTYPE CONSOLE}
uses
 SysUtils,
 windows;
begin
 readln;
 LoadLibrary("finer_lib.dll");
 readln;
end.


 
Reindeer Moss Eater ©   (2004-10-29 14:48) [51]

Зашибись!

А где запуск чего либо из DLL?


 
Reindeer Moss Eater ©   (2004-10-29 14:50) [52]

Reindeer Moss Eater ©   (29.10.04 10:14) [4]
Или вообще не создан экземпляр


 
dms_main ©   (2004-10-29 14:51) [53]

а зачем после загрузки сразу выполняется begin...end.

begin
thread:=TMyThread.create(2,2);
thread.WaitFor;
end.

Можешь проверить.....


 
dms_main ©   (2004-10-29 14:52) [54]


> Reindeer Moss Eater ©   (29.10.04 10:14) [4]
> Или вообще не создан экземпляр

создается - проверено дэбагом....


 
Reindeer Moss Eater ©   (2004-10-29 14:52) [55]

Можешь проверить.....

Для начала надо проверить результат LoadLibrary


 
dms_main ©   (2004-10-29 14:54) [56]

возвращает хэндл....


 
Reindeer Moss Eater ©   (2004-10-29 14:59) [57]

Код между бегин енд выполнятеся при загрузке процессом.
А выполняется ли он если библиотека грузится вторичным потоком этого процесса?


 
dms_main ©   (2004-10-29 15:02) [58]

Судя по тому что здесь>
inherited create(false);
  a:=a0;
  b:=b0;
  FreeOnTerminate:=true;
брэкпоинты - и на них выполнение останавливается, то грузит...


 
Reindeer Moss Eater ©   (2004-10-29 15:05) [59]

Поток грузит библиотеку. И Хендл валидный.

Но это вторичный поток и я не уверен, что в этом случае выполняется код между бегин и енд.
Надо поднимать литературу.


 
dms_main ©   (2004-10-29 15:07) [60]

так бы и сразу - а то "руки кривые","медицина бессильна".... :-(
подскажите хоть в каком направлении копать.


 
Reindeer Moss Eater ©   (2004-10-29 15:09) [61]

Экспортируй функцию из DLL и вызывай её явно, а не полагайся на Windows


 
dms_main ©   (2004-10-29 15:11) [62]

щас попробую..


 
Digitman ©   (2004-10-29 15:17) [63]


> dms_main


цитирую тебя :

constructor TMyThread.create(a0,b0:integer);
begin
  inherited create(false);
  a:=a0;
  b:=b0;
  FreeOnTerminate:=true;
end;

какого шута ты делаешь
inherited create(false);

!?

ведь доп.поток при этом начинает работать практически немедленно !

на основании чего ты уверен, что строка в конструкторе

   a:=a0;

выполнится заведомо раньше, чем строка

 c:=a*b;

в теле Execute ?

мозжечком-то пошевели малясь !


 
Reindeer Moss Eater ©   (2004-10-29 15:20) [64]

Все проще оказалось.

Код между бегин-енд в модуле библиотеки вызывается один раз на весь процесс.


 
dms_main ©   (2004-10-29 15:23) [65]


> на основании чего ты уверен, что строка в конструкторе

на основании того что execute вызывается ПОСЛЕ create
кстати от темы опять уходим.....


> Все проще оказалось.
>
> Код между бегин-енд в модуле библиотеки вызывается один
> раз на весь процесс.

и что из этого следует???


 
Reindeer Moss Eater ©   (2004-10-29 15:25) [66]

и что из этого следует???

То, что кто-то до сих пор с ручника не снялся.


 
dms_main ©   (2004-10-29 15:26) [67]


library finer_lib;

uses
 SysUtils,windows,
 Classes;

type TMyThread = class (TThread)
a:integer;
b:integer;
c:integer;
constructor create(a0,b0:integer);
destructor free;
procedure execute;override;
end;

constructor TMyThread.create(a0,b0:integer);
begin
   inherited create(false);
   a:=a0;
   b:=b0;
   FreeOnTerminate:=true;
end;

destructor TMyThread.free;
begin
   inherited free;
end;

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;

{$R *.RES}
procedure run;stdcall;export;
var
thread:TMyThread;
begin
thread:=TMyThread.create(2,2);
thread.WaitFor;
end;
exports run;
begin
end.

program Project1;
{$APPTYPE CONSOLE}
uses
 SysUtils,
 windows;
var
run : procedure;
handle:THandle;
begin
 readln;
 @run:=nil;
 handle:=LoadLibrary("finer_lib.dll");
 if  handle>= 32 then
       begin
       @run:=GetProcAddress(Handle,"run");
        if @run <> nil then
       run; ;
        end;
 FreeLibrary(Handle);
 writeln("ok");
 readln;
 readln;
end.



Всем спасибо - все заработало, но всетаки интересен вопрос
- реально ли запустить этот трэд в begin..end библиотеки???


 
dms_main ©   (2004-10-29 15:27) [68]


> Reindeer Moss Eater ©   (29.10.04 15:25) [66]
> и что из этого следует???
>
> То, что кто-то до сих пор с ручника не снялся.

весь день на нервах , так что уж извиняйте.... :-)


 
Reindeer Moss Eater ©   (2004-10-29 15:28) [69]

Реально.
Один раз за все время существования процесса.


 
Digitman ©   (2004-10-29 15:31) [70]


> все заработало


да не будет это работать как положено !
см. [63]


> реально ли запустить этот трэд в begin..end библиотеки


запустить любой код реально !
только вот будет ли он (конкретный твой код) делать то, что от него ожидается - это еще бабушка надвое сказала ...


 
dms_main ©   (2004-10-29 15:32) [71]


> То, что кто-то до сих пор с ручника не снялся.

- это точно......
Может объясните????
мне собственно и надо 1 раз , а не 2 и не 10.....
как заставить это работать без экспорта?


 
dms_main ©   (2004-10-29 15:33) [72]


> да не будет это работать как положено !
> см. [63]

с экспортом уже работает...


 
Reindeer Moss Eater ©   (2004-10-29 15:34) [73]

как заставить это работать без экспорта?

Чё, пошлины экспортные давят?


 
dms_main ©   (2004-10-29 15:35) [74]


> Чё, пошлины экспортные давят?

ага причем сильно..... :-))


 
Reindeer Moss Eater ©   (2004-10-29 15:37) [75]

Все это напоминает ток-шоу с приглашенными актерами.
Но актеры эти приглашенные, надо отдать должное здешним спецам по кастингу, иногда просто гениальные попадаются.
Именно гениальные. Снимаю шляпу.


 
dms_main ©   (2004-10-29 15:39) [76]

А если серьезно?


 
Reindeer Moss Eater ©   (2004-10-29 15:39) [77]

Так ведь работает уже


 
Digitman ©   (2004-10-29 15:40) [78]

просто вызови конструктор трэда в теле begin..end библиотеки.
что этому мешает ?


 
dms_main ©   (2004-10-29 15:41) [79]


> Так ведь работает уже

с экспортом - да ,а без экспорта - нет.
Я и спросил можно ли без экспорта и если да - то как.


 
dms_main ©   (2004-10-29 15:42) [80]


> просто вызови конструктор трэда в теле begin..end библиотеки.
> что этому мешает ?

А я что сделал?

begin
thread:=TMyThread.create(2,2);
thread.WaitFor;
end.


 
Digitman ©   (2004-10-29 15:46) [81]


> dms_main ©   (29.10.04 15:42) [80]


> А я что сделал?


и что ? и продолжаешь утверждать, что управление методу Execute не передается в ходе старта трэда ?


 
Добрый дядька ©   (2004-10-29 15:48) [82]

>dms_main

Вопрос:

Зачем нужна такая библиотека, которая загружается в приложение, выполняя код один раз, затем висит, занимая ресурсы?


 
dms_main ©   (2004-10-29 15:48) [83]

ДА именно так
Делаю LoadLibrary - креатиться, а execute не вызывается - из-за этого и вся проблема.


 
Reindeer Moss Eater ©   (2004-10-29 15:50) [84]

Который поток первый загрузил DLL - того и тапки.
Для него и будет выполнен код между begin/end.

Остальные отдыхают.


 
dms_main ©   (2004-10-29 15:53) [85]


> Который поток первый загрузил DLL - того и тапки.
> Для него и будет выполнен код между begin/end.
>
> Остальные отдыхают.

это все понятно - begin..end - вызывается 1 раз
при loadlibrary выполняется begin..end? креатится трэд, прыгает на Waitfor и ждет пока тред завершится - а метод execute в трэде так и не вызывается.... :-(


 
Digitman ©   (2004-10-29 15:54) [86]


> dms_main ©   (29.10.04 15:48) [83]


ерунду не городи.

ставь брейкпойнты на строчках

 c:=a*b;

и

 thread:=TMyThread.create(2,2);

и лови эти брейкпойнты !

и попробуй только сказать, что ни один из них не "ловится"


 
Reindeer Moss Eater ©   (2004-10-29 15:55) [87]

при loadlibrary выполняется begin..end?

Чё, еще раз?
Ну давай еще один раз:

Сто раз вызови LoadLibrary - код межу begin end выполнится ровно один раз.


 
dms_main ©   (2004-10-29 15:57) [88]


> ерунду не городи.
>
> ставь брейкпойнты на строчках
>
>  c:=a*b;
>
> и
>
>  thread:=TMyThread.create(2,2);
>
> и лови эти брейкпойнты !
>
> и попробуй только сказать, что ни один из них не "ловится"

именно это и говорю......
И вообще тема разговора именно эта!!!
не веришь - скомпиляй код (сообщение 67) - без экспорта и
через loadlibrary.....


 
dms_main ©   (2004-10-29 15:59) [89]


> Чё, еще раз?
> Ну давай еще один раз:
>
> Сто раз вызови LoadLibrary - код межу begin end выполнится
> ровно один раз.

спасибо - это я уже давно понял...... оно и вызывается 1 раз  - креатит но execute не вызывает....


 
Reindeer Moss Eater ©   (2004-10-29 16:00) [90]

креатит но execute не вызывает....

Это потому что хэллоуин на носу.
Подожди до понедельника, будет тебе execute


 
Digitman ©   (2004-10-29 16:00) [91]


> без экспорта


да экспорт-то тут причем ?!
хоть он есть, хоть его нет - ну никак это не влияет на сабж !


> не веришь


представь себе - не верю !
и даже проверять не буду ..
и глубоко фиолетово к тому же, КАК грузится твоя ДЛЛ - статически или динамически ..

давай-ка рассказывай, как ты "ловишь" брейкпойнты ..


 
dms_main ©   (2004-10-29 16:03) [92]

Run>Parameters>Host Application>F9
"MyLib">Reload Symbol Table


 
dms_main ©   (2004-10-29 16:18) [93]

проверить кстати можно еще проще :

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 - не создается.


 
Добрый дядька ©   (2004-10-29 16:20) [94]

Все прекрасно работает как в таком виде:

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");


 
Digitman ©   (2004-10-29 16:21) [95]


> 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:21) [96]

Сорри, строка ResumeThread в конструкторе не нужна.


 
dms_main ©   (2004-10-29 16:25) [97]

I>
> Все прекрасно работает как в таком виде:

как было так и есть...<


 
Добрый дядька ©   (2004-10-29 16:25) [98]

А вот ошибка в твоем коде:

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:26) [99]


>
> {$R *.RES}
> var
> thread:TMyThread;
> begin
> thread:=TMyThread.create(2,2);
> thread.WaitFor;
> end.
>
> Это вторая.

а если мне надо дождаться его завершения?


 
Reindeer Moss Eater ©   (2004-10-29 16:27) [100]

Добрый дядька ©   (29.10.04 16:20) [94]
Все прекрасно работает как в таком виде:


Если делать это в одном потоке.


 
Добрый дядька ©   (2004-10-29 16:28) [101]

Вторая ошибка потому, что

FreeOnTerminate:=true;

Не может использоваться с

thread.WaitFor;


 
Добрый дядька ©   (2004-10-29 16:29) [102]

>Reindeer Moss Eater ©   (29.10.04 16:27)

Если делать это в одном потоке.

По условиям задачи разве не это нужно?


 
Reindeer Moss Eater ©   (2004-10-29 16:29) [103]

Добрый дядька ©   (29.10.04 16:28) [101]

Это не объясняет феномен невызова Execute


 
Reindeer Moss Eater ©   (2004-10-29 16:30) [104]

По условиям задачи разве не это нужно?

не это нужно по условиям задачи


 
Добрый дядька ©   (2004-10-29 16:30) [105]

В случае, если нужно дождаться завершения потока, то используется FreeOnTerminate := True,
затем
WaitFor
Free

Это из-за особенностей реализации TThread


 
Reindeer Moss Eater ©   (2004-10-29 16:31) [106]

Добрый дядька ©   (29.10.04 16:30) [105]

Это не объясняет феномен невызова Execute


 
dms_main ©   (2004-10-29 16:31) [107]

Digitman ©  
сорри забыл дописать перед пелодом ctrl+alt+m


 
Digitman ©   (2004-10-29 16:33) [108]


> dms_main ©   (29.10.04 16:26) [99]


> а если мне надо дождаться его завершения?


да ёшкин кот !!

мы тут о чем говорим ? о твоем утверждении, что Execute у тебя якобы не вызывается !

какого рожна ты стрелки переводишь на не имеющее отношения к проблеме строчку ? мало ли что там у тебя торчит в коде следом за конструктором потока ! ты стартовал поток как not suspended, исключения ты не получил при вызове конструктора, значит  Execute обязан был получить управление ! И абсолютно неважно, что у тебя там стоит следующей строчкой ! Правильность логики вызова WaitFor в данноим контексте - это совершенно иной вопрос !


 
Добрый дядька ©   (2004-10-29 16:35) [109]

[103] Reindeer Moss Eater ©   (29.10.04 16:29)
Добрый дядька ©   (29.10.04 16:28) [101]

Это не объясняет феномен невызова Execute

Именно объясняет.

Поток создается с Inherited(False), поточная функция просто не успевает начать выполняться.


 
dms_main ©   (2004-10-29 16:35) [110]


> мы тут о чем говорим ? о твоем утверждении, что Execute
> у тебя якобы не вызывается !

смотри 93 мессагу


 
Digitman ©   (2004-10-29 16:36) [111]


> ctrl+alt+m


ЭТО к чему ? опять стрелки переводишь ?
какое отношение состояние открытости IDE-окна имеет к проблеме ?


 
dms_main ©   (2004-10-29 16:37) [112]


>
> ЭТО к чему ? опять стрелки переводишь ?
> какое отношение состояние открытости IDE-окна имеет к проблеме
> ?

открывается окно загруженных модулей - так в своем делаешь Reload Symbol Table


 
Reindeer Moss Eater ©   (2004-10-29 16:40) [113]

Поток создается с Inherited(False), поточная функция просто не успевает начать выполняться.

И что же ей мешает?


 
dms_main ©   (2004-10-29 16:41) [114]


> Поток создается с Inherited(False), поточная функция просто
> не успевает начать выполняться.
>
> И что же ей мешает?

Да же если create(true) а потом resume - толку нет. :-(


 
Добрый дядька ©   (2004-10-29 16:42) [115]

>Reindeer Moss Eater ©   (29.10.04 16:40)

И что же ей мешает?

Я думаю, возникающий Exception, в результате чего процесс успешно терминируется системой вместе с вновь созданным(или не успевшим создаться) потоком.


 
Добрый дядька ©   (2004-10-29 16:43) [116]

>dms_main ©   (29.10.04 16:41)

Ты мой код попробовал? Выполняется?


 
Reindeer Moss Eater ©   (2004-10-29 16:44) [117]

в результате чего процесс успешно терминируется

Что-то мы про это не слышали от приглашенного актера


 
dms_main ©   (2004-10-29 16:44) [118]


> Добрый дядька ©   (29.10.04 16:43) [116]
> >dms_main ©   (29.10.04 16:41)
>
> Ты мой код попробовал? Выполняется?

выполняется  create, а execute - нет.


 
Добрый дядька ©   (2004-10-29 16:45) [119]

>Reindeer Moss Eater ©   (29.10.04 16:44)

Что-то мы про это не слышали от приглашенного актера

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


 
Добрый дядька ©   (2004-10-29 16:46) [120]

>dms_main ©   (29.10.04 16:44)

Т.е. ты в точности создал проект с кодом библиотеки и вызовом?


 
dms_main ©   (2004-10-29 16:46) [121]


> >Reindeer Moss Eater ©   (29.10.04 16:40)
>
> И что же ей мешает?
>
> Я думаю, возникающий Exception, в результате чего процесс
> успешно терминируется системой вместе с вновь созданным(или
> не успевшим создаться) потоком.

Странно - никаких исключений и ошибок я не наблюдаю......


 
Reindeer Moss Eater ©   (2004-10-29 16:47) [122]

Добрый дядька ©

Он в IDE его отлаживает если помнишь.


 
dms_main ©   (2004-10-29 16:48) [123]

> Добрый дядька - нет исправил свой в точности с указаниями
(зачем смысл то тотже)


 
Добрый дядька ©   (2004-10-29 16:50) [124]

>dms_main ©   (29.10.04 16:48)
(зачем смысл то тотже)

А ты не думаешь, что у тебя может быть проблема в коде, который ты используешь? Например, при работе с файлом?


 
dms_main ©   (2004-10-29 16:50) [125]

Мастера - насчет отладки - в execute создается файл - нету этого файла - несоздается он > execute не выполняется.


 
dms_main ©   (2004-10-29 16:51) [126]

В console Application тотже код работает без проблем.


 
Reindeer Moss Eater ©   (2004-10-29 16:54) [127]

Парень, сколько раз можно повторять, что у тебя не создается экземпляр, потому и нет execute.

А в отладчике есть создание потому что IDE загружает библиотеку первая.


 
dms_main ©   (2004-10-29 16:57) [128]


> Reindeer Moss Eater ©   (29.10.04 16:54) [127]
> Парень, сколько раз можно повторять, что у тебя не создается
> экземпляр, потому и нет execute.
>
> А в отладчике есть создание потому что IDE загружает библиотеку
> первая.

ok - тоесть без экспорта работать небудет?(файла то создаваемого нет)


 
Digitman ©   (2004-10-29 16:59) [129]

я, кажись, начинаю понимать, в чем дело ..
это, видимо, известный глюк на стыке встроенного дебаггера и ВинХРю без апдейта ...

т.е. Execute-то как раз выполняется, но вот из-за глюка дебаггер не может отработать брэйкпойнт в теле поточной ф-ции

но даже если так, то MessageBox (ПЕРВОЙ же строчкой после begin в Execute)  обязан зафиксировать факт успешного старта поточной ф-ции... если, конечно же, не умудриться напортачить еще и с параметрами MessageBox..


 
dms_main ©   (2004-10-29 17:04) [130]

> Digitman ©
винда ХР со всеми патчами,D7 без мудрежа дэббагит,
нету ни файла ни месседж бокса ни меесадж бипа.


 
Digitman ©   (2004-10-29 17:09) [131]


> dms_main ©   (29.10.04 17:04) [130]


да ну не верю я !

ты что-то существенное скрываешь, то что упорно не приводишь в примерах своего кода ..

почему ты до сих пор не оттрассировал пошагово тело конструктора TThread ?


 
dms_main ©   (2004-10-29 17:15) [132]

вот те другой мой код в котором таже беда - невижу смысла выкладывать 14к кода если в 0,7к таже беда:

library finer_lib;

uses
 SysUtils,windows,
 Classes;

type TMyThread = class (TThread)
a:integer;
b:integer;
c:integer;
constructor create(a0,b0:integer);
destructor free;
procedure execute;override;
end;

constructor TMyThread.create(a0,b0:integer);
begin
   inherited create(true);
   a:=a0;
   b:=b0;
  // FreeOnTerminate:=true;
   resume;

end;

destructor TMyThread.free;
begin
   inherited free;
end;

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;

{$R *.RES}

var
thread:TMyThread;
begin
delete
thread:=TMyThread.create(2,2);
thread.WaitFor;
end.


 
Добрый дядька ©   (2004-10-29 17:16) [133]

Так тоже дебаггер не заходит в поточную функцию?


library ThrDll;

uses
 windows;

type
 TParm=record
   X,Y: Integer;
 end;
var
 Parm: TParm;
 ThreadId: THandle;

procedure ThreadFunc(aParm: Pointer); cdecl;
var
 i: Integer;
begin
 for i := 0 to TParm(aParm^).X do
 begin
   Write("Test"+#13#10);
 end;
end;

begin
 Parm.X := 2;
 Parm.Y := 2;
 CreateThread(nil,0,@ThreadFunc,@Parm,0,ThreadId);
end.


 
Reindeer Moss Eater ©   (2004-10-29 17:18) [134]

Код приглашенного актера прекрасно работает в консольном приложении (читай - в однопоточном) - давайте верить в это.

В многопоточном не работает как надо. - давайте тоже верить в это.

Значит где трабл зарыт?
Правильно. В особенности парочки DLL + вторичный поток.

Не понимаю, как можно в течении 130 постов обсуждать очевидное.


 
dms_main ©   (2004-10-29 17:18) [135]

Добрый дядька © >
это - совершенно другая песня здесь заходит.


 
Digitman ©   (2004-10-29 17:19) [136]


> dms_main ©   (29.10.04 17:15) [132]


и долго ты еще будешь постить сюда один и тот же код в разных вариациях ?

я тебе вопрос задал - ЧТО показала пошаговая трассировка TThread.Create() ?


 
dms_main ©   (2004-10-29 17:20) [137]

Reindeer Moss Eater © > несогласен только с одним - "приглашенный актер" интересно это к чему? :-(


 
Reindeer Moss Eater ©   (2004-10-29 17:21) [138]

ЧТО показала пошаговая трассировка TThread.Create() ?

Ничего полезного она не покажет.

Отладчик туда зайдет, потому что либа бкдет все же загружена.
Но вторичный поток загрузив либу, не заставит отладчик зайти туда.


 
dms_main ©   (2004-10-29 17:21) [139]


> Digitman ©

весь код который в create выполнился, в execute не заходит.


 
Reindeer Moss Eater ©   (2004-10-29 17:24) [140]

Reindeer Moss Eater © > несогласен только с одним - "приглашенный актер" интересно это к чему? :-(

Потому что программер на форуме решает реальные проблемы, а приглашенный актер играет роль.


 
Digitman ©   (2004-10-29 17:25) [141]


> Reindeer Moss Eater ©   (29.10.04 17:18) [134]


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

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

или ты намекаешь на то, что до CreateThread даже дело не доходит ? но в Д5, по кр.мере, обязано доходить !


 
dms_main ©   (2004-10-29 17:26) [142]


> Reindeer Moss Eater ©

то есть получается я от нефиг делать тут весь день торчу ? :-(

> Потому что программер на форуме решает реальные проблемы

и трабла моя вымышлена?


 
Reindeer Moss Eater ©   (2004-10-29 17:28) [143]

Разница такая.

Мы ставим BP.
И мы попадем на эту BP.
Но это не та нить, которую мы отлаживаем.

У него нет следов файла, который должен появиться в результате загрузки либы вторичным потоком.

Точка останова есть, и мы туда попадаем.
Но только не тогда, когда вторичный поток делает LoadLobrary


 
dms_main ©   (2004-10-29 17:30) [144]


> Но только не тогда, когда вторичный поток делает LoadLobrary

Я это все давно понял - можно не повторяться.
Лечиться это или нет - вот в чем вопрос.


 
dms_main ©   (2004-10-29 17:30) [145]


> Но только не тогда, когда вторичный поток делает LoadLobrary

Я это все давно понял - можно не повторяться.
Лечиться это или нет - вот в чем вопрос.


 
Reindeer Moss Eater ©   (2004-10-29 17:32) [146]

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

Устал я. Домой иду.


 
Digitman ©   (2004-10-29 17:35) [147]


> Reindeer Moss Eater ©   (29.10.04 17:21) [138]


с какой стати отладчик автоматом загрузит ДЛЛ, если она в хост-приложении грузится искл-но динамически ? и если никаких Reload Symbol Table и иже с ним сомнительных фич не задействовать явно ?


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

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


 
Reindeer Moss Eater ©   (2004-10-29 17:41) [149]

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

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

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

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

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

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

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


 
Reindeer Moss Eater ©   (2004-10-29 17:52) [150]

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

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


 
Defunct ©   (2004-10-29 19:07) [151]

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

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

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

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


 
Reindeer Moss Eater ©   (2004-11-01 10:40) [152]

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

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.


 
Digitman ©   (2004-11-01 11:50) [153]


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


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

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


 
DiamondShark ©   (2004-11-01 12:41) [154]

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

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


 
Reindeer Moss Eater ©   (2004-11-01 12:43) [155]

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

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


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

DiamondShark ©

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


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


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


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

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


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


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


 
DiamondShark ©   (2004-11-01 13:04) [158]


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

Это ты к чему?


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

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


 
DiamondShark ©   (2004-11-01 13:14) [159]

Объясняю.

Вызываем 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.


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

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

Проблема 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:24) [161]

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


 
Digitman ©   (2004-11-01 13:32) [162]


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


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


 
DiamondShark ©   (2004-11-01 13:40) [163]


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

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


 
Reindeer Moss Eater ©   (2004-11-01 13:50) [164]

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

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


 
Digitman ©   (2004-11-01 13:58) [165]

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

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


 
DiamondShark ©   (2004-11-01 14:28) [166]


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

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

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


 
dms_main ©   (2004-11-02 22:11) [167]

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



Страницы: 1 2 3 4 5 вся ветка

Форум: "Основная";
Текущий архив: 2004.11.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.9 MB
Время: 0.062 c
14-1098465723
Кириешки
2004-10-22 21:22
2004.11.14
From SPYWARE to WARNING.


3-1097650762
AZ
2004-10-13 10:59
2004.11.14
Ограничения FireBird


14-1099058767
Knight
2004-10-29 18:06
2004.11.14
МиниЛинух... только роутер или можно почту и web прикрутить?


14-1098701040
вразлет
2004-10-25 14:44
2004.11.14
Вот как надо подрывать буржуйскую экономику)))


8-1092378491
Maxx217
2004-08-13 10:28
2004.11.14
Масштабирование картинки





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский