![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
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;