Параметр для CreateThread

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Функции для потока нужно передать два параметра: строку и целое (условно текст для окна и HWND окна, не суть важно).
Создаю структуру

Код: Выделить всё

TPRMSG = record
    msg: PChar;  
    hwndPR: hWND; 
end;
Объявляю переменную prmsg упомянутого типа и перед созданием треда её заполняю:

Код: Выделить всё

    Move(msg,prmsg.msg,length(msg));
    // аналог prmsg.msg:=PChar(msg); даёт тот же результат
    prmsg.hwndPR:=hwndLabel;
и создаю новый поток:

Код: Выделить всё

thr := CreateThread(0, 0, @ThreadedProc, @prmsg, 0, thrID);
Соответственно так разбираю параметр:

Код: Выделить всё

function ThreadedProc(prm: Pointer) :Integer; stdcall;
var 
  prmsg: TPRMSG;
  ...
begin
   if Assigned(prm) then
    begin
        prmsg:= TPRMSG(prm^);
        MessageBox(0,Pchar(' Threaded= '+prmsg.msg+'!'),'info', mb_OK);
    end;
    ...
end;
Дык вот, в messagebox при некоторых исходных строках почему-то
происходит урезание последнего символа. Тот же самый текст, запущенный
в тестовом приложении (мемо+кнопка) вообще неожиданно вываливается
с левым сообщением Canvas does not allow drawing (под Trace Into однако нормально отрабатывает).
Т.е. налицо моя ошибка, вот только куда копать понять не могу.
Аналогичный вызов с дельфёвским классом в качестве параметра работает
без проблем.
Буду благодарен за любые предположения...
Даже самый дурацкий замысел можно воплотить мастерски
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Прокатил метод ненаучного тыка: в структуре поменял объявление msg c PChar на String и присвоение перед созданием потока: prmsg.msg:=msg; Однако в природе такого поведения хотелось бы разобраться...
Даже самый дурацкий замысел можно воплотить мастерски
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

А цепочка символов где лежит? PChar - это же указатель. Он должен указавать на какой-то буффер. Наверное этот буфер как-то разрушается к моменту использования указателя.
Да и вообще
1) Хендл возвращаемый CreateThread надо закрывать через CloseHandle
2) Порождение треда это дорогая операция
Так что надо лучше создать постоянный тред, который спит в ожидании какого-то события, и если надо показать диалоговую панельку, этот тред пробуждать.
2B OR NOT(2B) = FF
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Absurd, переменная объявлена на уровне модуля. Т.е. по идее ничего не разрушается, коль скоро я копирую память с помощью Move. Возможно я криво копирую...
По вообще:
1) В какой момент его закрывать?
2) Это вообще выше моего понимания. У меня главный поток спит. При необходимости запускает новый поток, который лезет в и-нет, скачивает инфу и отображает её в окне. Подскажи хотя бы функции, которыми подобное поведение организовать можно.

У меня кстати, де факто получился неумирающий сокет внутри потока, хотя он явно закрывается...
Даже самый дурацкий замысел можно воплотить мастерски
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

msg - это указатель длиной в 32 бита. Командой Move ты копируешь указатель, а не строку.
По вообще:
1) Когда тред отработает, надо посмотреть его код возврата ( GetExitCodeThread() ) и закрыть его хендл.
2) Бесконечный цикл с блокированием

Код: Выделить всё

void threadproc(...) {
  while(true) {
    WaitForSingleObject(hEvent,INFINITE);
    if (exitFlag) break;
    infoFromInet = GoInet(...);
    DisplayInfo(infoFromInet);
  }
}
Когда основной поток должен чего-то вывести, он должен перевести hEvent в сигнальное состояние. Если он завершает свою работу, он должен сделать exitFlag:= true и перевести hEvent в сигнальное состояние, дождаться завершения треда (WaitForSingleObject(hThread,INFINITE) ), и закрыть этот тред (CloseHandle(hThread) ).
2B OR NOT(2B) = FF
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Absurd, спасибо, буду думать.
Кстати, хендл можно закрывать, когда он не нужен для дальнейшего использования - процесс это не останавливает.
Даже самый дурацкий замысел можно воплотить мастерски
Ответить