Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.02.2012, 02:50   #1
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
Восклицание передача потоку 2 и более параметра через createthread

Эта тема уже поднималась, но в ней было передача 1 параметр а больше как? Чет я не пойму как ((


Код:
procedure MyProcedure(param: pointer);  stdcall;
var
  str : String;
begin
str:=PChar(param);
showmessage(str);
StrDispose(PChar(param));
end;

procedure TForm6.Button1Click(Sender: TObject);
var
str: string;
begin
str:='привет';
createthread(nil,0,@MyProcedure,StrNew(PChar(str)),0,trid);
Это старый код, что суда дописать ? что бы передать больше параметров подскажите или покажите.
у меня проблема именно вот тут
Код:
createthread(nil,0,@MyProcedure,StrNew(PChar(str)),0,trid);
как туда присобачить больше параметров не пойму.

Последний раз редактировалось fucil; 08.02.2012 в 02:53.
fucil вне форума Ответить с цитированием
Старый 08.02.2012, 02:58   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

Прочитать MSDN по CreateThread....
Посмотреть реализацию класса TThread...
Человек_Борща вне форума Ответить с цитированием
Старый 08.02.2012, 04:02   #3
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию

Та я смотрел, только не помню где, может и на mdsn, но придумать как передать 2 параметра не могу!
Там все в примерах на 1 параметре, ты невнимательно прочел пост, я же написал что проблема в передаче, как это написать в синтаксисе ?
при этом половина мозга отказывается думать и это горькая правда.

Последний раз редактировалось fucil; 08.02.2012 в 04:07.
fucil вне форума Ответить с цитированием
Старый 08.02.2012, 08:29   #4
Silver_S
Форумчанин
 
Регистрация: 14.03.2011
Сообщений: 104
По умолчанию

Передавайте 1 параметр - указатель на запись, содержащую все остальные параметры
Silver_S вне форума Ответить с цитированием
Старый 09.02.2012, 02:51   #5
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
Восклицание

а пример можно? По незнанию не могу реализовать !
У меня нет опыта с указателями ((
И промежуточный вопрос @MyProcedure
@ - собака в начале это что ? для чего используют (есть подозрение что это и есть указатель на область памяти где находиться что то)

Последний раз редактировалось fucil; 09.02.2012 в 02:54.
fucil вне форума Ответить с цитированием
Старый 09.02.2012, 03:20   #6
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию

Цитата:
Сообщение от fucil Посмотреть сообщение
а пример можно? По незнанию не могу реализовать !
У меня нет опыта с указателями ((
И промежуточный вопрос @MyProcedure
@ - собака в начале это что ? для чего используют (есть подозрение что это и есть указатель на область памяти где находиться что то)
Только что ознакомился с указателями )) очень интересно... После понял суть которую хотел донести мне Silver_S, но как это будит выглядить программно, пока не придумал.

Последний раз редактировалось fucil; 09.02.2012 в 03:24.
fucil вне форума Ответить с цитированием
Старый 09.02.2012, 04:05   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

По рукам за CreateThread, неверный прототип и отсутствие обработки ошибок.

Код:
type
  TThreadParam = record
    I1: Integer;
    P2: Pointer;
    S3: String;
    // пиши что угодно
  end;
  PThreadParams = ^TThreadParams;

...

function ThreadProc(Parameter: Pointer): Integer;
var
  Params: TThreadParams;
begin
  try
    Params := PThreadParams (Parameter)^;
    FreeMem(Parameter);

    ... твой код, использующий параметры из Params

    Result := 0;
  except
    Result := ERROR_GEN_FAILURE;
  end;
end;

...

var
  Params: PThreadParams;
  TH: THandle;
  TID: Cardinal;
begin
  Params := AllocMem(SizeOf(TThreadParams));
  Params.I1 := 42;
  Params.S3 := 'Show me the money';

  TH := BeginThread(nil, 0, ThreadProc, Params, 0, TID);
  Win32Check(TH <> 0);
  // ... тут можно разместить код, если надо
  CloseHandle(TH);
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 09.02.2012, 12:10   #8
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Разрешите малость уточнить.

Аккуратен ли подход при аллоке памяти в клиентском коде и освобождении во внешнем ? Ведь тем более что производится обработка ошибок - значит подразумеваем возможность невыполнения внешней процедуры.
Ну и плюсом - AllocMem вроде непарная функция FreeMem (для FreeMem парна GetMem, хотя полагаю тут может быть зависимость от менеджера памяти), так ведь ? Обычно же рекомендуется использовать парные подпрограммы выделения-освобождения памяти, можно разъяснить сей момент, погуглил - не особо нащупал.

Для ТС замечу, чтобы не было путаницы - объявлена переменная указательного типа, но при использовании не разыменовывается, это в порядке вещей, дельфи это позволяет при подобном использовании типизированного указателя на записи.

Кстати )))
http://www.transl-gunsmoker.ru/2009/09/blog-post.html
Цитата:
Сообщение от GunSmoker
Для записей, синтаксис языка позволяет вам опускать оператор ^, если код не теряет при этом своего смысла. Но лично я всегда явно указываю оператор для улучшения читабельности.
Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Код:
  Params := AllocMem(SizeOf(TThreadParams));
  Params.I1 := 42;
  Params.S3 := 'Show me the money';
phomm вне форума Ответить с цитированием
Старый 09.02.2012, 13:15   #9
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Аккуратен ли подход при аллоке памяти в клиентском коде и освобождении во внешнем ?
Да, по хорошему туда надо добавить if TH = 0 then FreeMem(Params); перед Win32Check.

Цитата:
Ну и плюсом - AllocMem вроде непарная функция FreeMem
Парная. AllocMem - это GetMem + ZeroMemory.

Цитата:
Кстати )))
Почему-то подумалось, что для примера начинающему будет лучше с неявным разыменованием.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 09.02.2012, 13:25   #10
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Гм... откуда у меня там вообще AllocMem?

Код вчера писал на коленке и уже засыпая. Там вообще должно стоять New и Dispose.

Итого, должно быть как-то так:
Код:
type
  TThreadParam = record
    I1: Integer;
    P2: Pointer;
    S3: String;
    // пиши что угодно
  end;
  PThreadParams = ^TThreadParams;

...

function ThreadProc(Parameter: Pointer): Integer;
var
  Params: TThreadParams;
begin
  try
    Params := PThreadParams (Parameter)^;
    Dispose(PThreadParams(Parameter));

    ... твой код, использующий параметры из Params

    Result := 0;
  except
    Result := ERROR_GEN_FAILURE;
  end;
end;

...

var
  Params: PThreadParams;
  TH: THandle;
  TID: Cardinal;
begin
  TH := 0;
  New(Params);
  try
    Params.I1 := 42;
    Params.P2 := nil; // <- добавлено, т.к. New не чистит память, поэтому надо явно инициализировать
    Params.S3 := 'Show me the money';

    TH := BeginThread(nil, 0, ThreadProc, Params, 0, TID);
    Win32Check(TH <> 0);
  finally
    if TH = 0 then
      Dispose(Params);
  end;

  // ... тут можно разместить код, если надо

  CloseHandle(TH);
end;
Ну а если с AllocMem, то так:
Код:
type
  TThreadParam = record
    I1: Integer;
    P2: Pointer;
    S3: String;
    // пиши что угодно
  end;
  PThreadParams = ^TThreadParams;

...

function ThreadProc(Parameter: Pointer): Integer;
var
  Params: TThreadParams;
begin
  try
    Params := PThreadParams (Parameter)^;
    Finalize(PThreadParams(Parameter)^);
    FreeMem(Parameter);

    ... твой код, использующий параметры из Params

    Result := 0;
  except
    Result := ERROR_GEN_FAILURE;
  end;
end;

...

var
  Params: PThreadParams;
  TH: THandle;
  TID: Cardinal;
begin
  TH := 0;
  Params := AllocMem(SizeOf(TThreadParams));
  try
    Params.I1 := 42;
    Params.S3 := 'Show me the money';

    TH := BeginThread(nil, 0, ThreadProc, Params, 0, TID);
    Win32Check(TH <> 0);
  finally
    if TH = 0 then
    begin
      Finalize(Params^);
      FreeMem(Params);
    end;
  end;

  // ... тут можно разместить код, если надо

  CloseHandle(TH);
end;
Удаление блока вынесено за Win32Check в finally, чтобы FreeMem/Dispose не попортили бы GetLastError от BeginThread. Вместо этого можно было делать так:

Код:
    TH := BeginThread(nil, 0, ThreadProc, Params, 0, TID);
    SavedError := GetLastError;
    Dispose(Params);
    SetLastError(SavedError);
    Win32Check(TH <> 0);
но это потребует лишней переменной.

P.S. Код снова писал на коленке, могут быть опечатки.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
createthread и передача параметра процедуре fucil Win Api 9 19.01.2012 19:19
передача параметра маГГ85 PHP 4 18.01.2012 11:35
Передача метода класса в CreateThread mike_tihomirov Win Api 3 17.07.2010 14:13
Передача параметра с MDI родителя в MDI child через DLL ByXalkin Общие вопросы Delphi 0 15.12.2009 17:21
передача параметра по ссылке veter_s_morya PHP 7 18.10.2009 16:43