Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

CreateThread [D6, NT4, Win2k]


Nevmerj ©   (2002-03-13 13:25:00) 

Подскажите как передать число в поток

procedure mythread(P:Pointer);
begin
if p=nil then WriteLn("Error"); // почему то всегда p=nil !!! :(
end;

var param : Cardinal;

param:=10;
createThread(nil,0,@mythread,Pointer(param),0,ThId); или
createThread(nil,0,@mythread,@param,0,ThId);

Ни один из этих вариантов не работает - p=nil :( Подскажите как правильно это сделать??


VuDZ   (2002-03-15 21:38:00) [1]

да можно и ООП сделать на чистом С/Паскале, а надо ли...

В общем: люди, будьте внимательны к той фигне, которую вы пишите :)


paul_shmakov   (2002-03-15 20:05:00) [2]

да конечно разницы между procedure и function - никакой. я тоже пишу в основном на cpp, а delphi относительно слабо знаю :)

просто сегодня программер напишет void WINAPI ThreadFunc(LPVOID lpParam), а завтра здесь же будет спрашивать, почему GetExitCodeThread возвращает непонятное значение и откуда она его берет?

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

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

чем меньше таких допусков (непозволительных, кстати) - тем лучше.


VuDZ   (2002-03-15 16:23:00) [3]

сорри,но я пишу на С/С++, и особо не знаю, в чем разница на Делфи у procedure & function
единственная ф-ия, возвращаемое значение которое точно нужно - GetLastError()
я в этом вопросе (портирование API -> Delphi) не очень, так что спорить не буду


paul_shmakov   (2002-03-15 11:25:00) [4]

2 VuDZ:

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

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

а то они потом все начинают опускать - и возвращаемое значение, и stdcall, и даже количество параметров (!) - это мол все пережитки с/с++. :)

так что, чем строже, тем лучше. ошибок и своих хватит.


VuDZ   (2002-03-15 07:46:00) [5]

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

> но из MSDN (надеюсь они то знают, что пишут ).

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


paul_shmakov   (2002-03-15 07:33:00) [6]

не смотрите на дурные примеры :)
DWORD WINAPI ThreadFunc( LPVOID );

2 VuDZ:
да всё это фигня, на самом-то деле
ну зачем людей смущаешь? :)


Nevmerj   (2002-03-15 07:26:00) [7]

VOID InstanceThread(LPVOID lpvParam)

Это из примера не по потокам, но из MSDN (надеюсь они то знают, что пишут ). Я автоматом так и написал procedure..


VuDZ   (2002-03-15 02:32:00) [8]

да всё это фигня, на самом-то деле.
3/4 потоков у меня определены так:
voidDowork (void* param)
т.е. они ничего не возвращают

так же как и глвная ф-ия приложения: может быть int WinMain(), а может void WinMain()


Юрий Зотов   (2002-03-14 20:50:00) [9]

> Nevmerj (13.03.02 23:18)

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

Из SDK:

lpStartAddress

The starting address of the new thread. This is typically the address of a function declared with the WINAPI calling convention that accepts a single 32-bit pointer as an argument and returns a 32-bit exit code. Its prototype is: DWORD WINAPI ThreadFunc( LPVOID );

Что на Паскале выглядит как:
function MyThread(P: Pointer): DWORD; stdcall;



Из MSDN (ThreadProc):

The function should return a value that indicates its success or failure.


VuDZ   (2002-03-14 18:08:00) [10]

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

А остальне 600 в классах :>


Shaman_Naydak   (2002-03-14 17:02:00) [11]

>> VUDZ
Код имеет мрачную способность разбухать..
и эти десять строк кода легко и без усилий вырастут в 500-700, понадобится синхронизировать чо-нидь с основным потоком, и понеслась..
Конечно, сделать самому не проблема, но зачем?

>> Nevmerj
Еще раз советую использовать оболочку BeginThread, ну или хотя бы сам присвой IsMultiThreaded:=True..
а то будешь долго искать ошибка у борланада в выделении/освобождении памяти..


Nevmerj   (2002-03-13 23:18:00) [12]

Проблема была в stdcall

2 Юрий Зотов
А почему процедура? Должна быть функция.
Потому, что так написано в примере в MSDN (пример не о CreateThread )


VuDZ   (2002-03-13 17:19:00) [13]

Shaman_Naydak

> А вообще-то нормальные люди класс наследуют от TThread"a
> и не создают себе трудностей на ровном месте

ну-ну - из-за десяти строк кода делать класс?

void* thread(void *param){
int num = (int)param;
....
}

_beginthread (thread, 0, (void*)123);

смысл ясен?


Shaman_Naydak   (2002-03-13 13:52:00) [14]

Если сильно хочется геморроя то,
BeginThread(nil, 0, @MyThread, @Param, 0, ThID);
вместо CreateThread"a надо использовать оболочку, чтобы потом память корректно выделялась..
Вот пример:
type
PCardinal = ^Cardinal;
function MyThread(Param: PCardinal): Integer;
var
FreeThread: Boolean;
begin
if Param = nil then
ShowMessage("nil")
else
ShowMessage(IntToStr(Param^));

EndThread(0);
end;


var P: Cardinal;

procedure TForm1.Button3Click(Sender: TObject);
var ThID: LongWord;
begin
P:=10;
BeginThread(nil, 0, @MyThread, @P, 0, ThID);
end;

А вообще-то нормальные люди класс наследуют от TThread"a
и не создают себе трудностей на ровном месте


Юрий Зотов   (2002-03-13 13:44:00) [15]

1. А почему процедура? Должна быть функция.
2. Нарушено соглашение о вызове. Нужно stdcall.

function MyThread(P: Pointer): DWORD; stdcall;


Наверх

Титульная страница Поиск, карта сайта Написать письмо