Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки, Передача более одного параметра 
:(
    Опции темы
Гость_Felt
Дата 12.7.2005, 14:49 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Код
procedure ThreadProc(vSocket: Integer; CommandLine: String); stdcall;
begin
 ShowMessage(IntToStr(vSocket));
 ShowMessage(CommandLine);
 ExitThread(0);
end;

procedure TForm1.Button1Click(Sender: TObject);
type
 ThreadProcParam = record
  vSocket: Integer;
  CommandLine: String;
 end;
var
 hTh, hThread: THandle;
 Param: ThreadProcParam;
begin
 Param.vSocket:=5;
 Param.CommandLine:='Hello world';
 hThread:=CreateThread(nil, 0, @ThreadProc, Pointer(Param), 0, hTh);
 WaitForSingleObject(hThread, INFINITE);
 Windows.CloseHandle(hThread);
end;

Функция CreateThread может передавать в поток только один параметр, поэтому я решил создать структуру и передать ее. Но теперь Delphi упорно не хочет компилировать этот код. Задача такая: мне нужно передать в поток число и строку, поток должен показать мне значения в диалоговых окнах и завершиться. Использовать глобальные переменные нельзя, так как программа многопользовательская и переменные могут перезаписать другие пользователи, работающие с программой.
  Вверх
_hunter
Дата 12.7.2005, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 9
Всего: 98



во-первых: ThreadProc() тоже должна знать о структуре ThreadProcParam поэтому нужно сделать ее публичной
во-вторых: от того, что ты передаеш в ThreadProc структуру параметры ThreadProc не меняются
и в-третьих: в ThreadProc должен передаваться адрес структуры, а не она сама, приведенная к указателю


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Guest
Дата 12.7.2005, 15:27 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Код
type
ThreadProcParam = record
  vSocket: Integer;
  CommandLine: String;
 end;

procedure ThreadProc(Param: ThreadProcParam); stdcall;
begin
 ShowMessage(IntToStr(Param.vSocket));
 ShowMessage(Param.CommandLine);
 ExitThread(0);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
 hTh, hThread: THandle;
 Param: ThreadProcParam;
begin
 Param.vSocket:=5;
 Param.CommandLine:='Hello world';
 hThread:=CreateThread(nil, 0, @ThreadProc, @Param, 0, hTh);
 WaitForSingleObject(hThread, INFINITE);
 Windows.CloseHandle(hThread);
end;

Программа впадает в бесконечный цикл.
  Вверх
Guest
Дата 12.7.2005, 15:30 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ой, млин... Программа просто зависает.
  Вверх
Guest
Дата 12.7.2005, 15:33 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А про использование глобальных переменных я спросил на тот случай если вы вообще откажетесь что то передавать, а посоветуете использовать глобальные переменные.
  Вверх
_hunter
Дата 12.7.2005, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 9
Всего: 98



странно что вообще собралось...
Код

DWORD WINAPI ThreadProc(
  LPVOID lpParameter
);

т.е. должен передаваться Pointer, который уже в функции должен приводиться к структуре...
кажется так ( давно в делфях не сидел )
procedure ThreadProc(Param: Pointer); stdcall;
begin
ShowMessage(IntToStr(ThreadProcParam(Param^).CommandLine));
ExitThread(0);
end;

+ строки так передавать нежелательно ( нужно через pchar() )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Guest
Дата 12.7.2005, 15:56 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Не компилируется. Хотя со строками, мне как раз PChar и нужно вызывать, просто я думал что проще будет через String ведь там есть размер строки, а преобразование хотел делать уже внутри потока.
  Вверх
Guest
Дата 12.7.2005, 16:00 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ой, снова виноват.
Код
type
ThreadProcParam = record
  vSocket: Integer;
  CommandLine: String;
 end;

procedure ThreadProc(Param: Pointer); stdcall;
begin
 ShowMessage(IntToStr(ThreadProcParam(Param^).vSocket));
 ExitThread(0); 
end;


procedure TForm1.Button1Click(Sender: TObject);
var
 hTh, hThread: THandle;
 Param: ThreadProcParam;
begin
 Param.vSocket:=5;
 Param.CommandLine:='Hello world';
 hThread:=CreateThread(nil, 0, @ThreadProc, @Param, 0, hTh);
 WaitForSingleObject(hThread, INFINITE);
 Windows.CloseHandle(hThread);
end;
Программа снова зависает.
  Вверх
_hunter
Дата 12.7.2005, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 9
Всего: 98



зависает где?
+ пройдись отладчиком по коду -- посмотри что в ThreadProcParam(Param^).vSocket
( возможно ты просто на Ok не жмеш )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
p0s0l
Дата 12.7.2005, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Тут всё дело в ShowMessage, т.к. он вызывает GetWindowText, а она работает через WM_GETTEXT. А кто сможет обработать сообщение, если основной поток ждёт завершения созданного потока, т.е. не обрабатывает сообщения ? Тупик!
Сделай так:
Код
procedure ThreadProc(Param: Pointer); stdcall;
begin
  MessageBox(0, PChar(IntToStr(ThreadProcParam(Param^).vSocket)), PChar(ThreadProcParam(Param^).CommandLine), 0);
end;




--------------------
С уважением, г-н Посол.
PM   Вверх
Guest
Дата 12.7.2005, 17:51 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо, все работает.
  Вверх
Guest
Дата 12.7.2005, 19:09 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











А как получить результат работы функции потока, т. е. поточная функция будет не процедурой как у меня, а функцией с возвращаемым значением типа Boolean?
Код
function ThreadProc(Param: Pointer): Boolean; stdcall;
begin
  Result:=False;
  MessageBox(0, PChar(IntToStr(ThreadProcParam(Param^).vSocket)), PChar(ThreadProcParam(Param^).CommandLine), 0);
end;

  Вверх
_hunter
Дата 12.7.2005, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 9
Всего: 98



во-первых: не bool, а dword ( что за странная тяга прототипы каверкать? )
а во-вторых: GetExitCodeThread()


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Guest
Дата 12.7.2005, 19:35 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Еще раз спасибо, очень помог.
  Вверх
Guest
Дата 12.7.2005, 20:09 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Ну и, наверно, последний вопрос по потокам (очень на это надеюсь!).
Код
procedure RunExternalProc(Params: Pointer); stdcall;
var
 Func: function(CommandLine: PChar): PChar; stdcall;
 Command, Buffer: PChar;
 Text: String;
begin
 Buffer:='';
 Command:=PChar(LowerCase(GetParam(0, TExternalProcParams(Params^).CommandLine)));
 Func:=GetProcAddress(TExternalProcParams(Params^).hDLL, Command);
 if Addr(Func) <> nil then
  begin
   Buffer:=Func(TExternalProcParams(Params^).CommandLine);
   if Buffer <> '' then
    begin
     ExitThread(1);
     Text:=Buffer;
//До этого места код выполняется, сокет тоже передается верный, 
//это я проверял через вызовы MessageBox в этой части кода 
//(Delphi не исполняет этот участок кода под отладчиком, 
//что вполне естественно).     
Send(TExternalProcParams(Params^).vSocket, Text[1], Length(Text), 0);
     //SendText(TExternalProcParams(Params^).vSocket, Text);
    //Убедившись что мой аналог функции Send не работает,
   // пришлось временно ее закоментировать
    end;
  end;
 ExitThread(0);
end;

Функция Send и мой аналог SendText прекрасно работают в программе, но отказываются работать внутри потока. Я не могу понять почему? До вызова потока WinSock не завершает свою работу, сокет тоже не закрывает. Почему программа отказывается посылать текстовую строку? Если это невозможно, тогда придется сделать так, чтобы поточная функция возвращала строку, а не число (у меня это 0 и 1 - аналоги True и False).
  Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0515 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.