Newsgroup: it.comp.lang.delphi
Titolo: BeginThread con parametri - strani accadimenti

Salve, mi trovo davanti ad un piccolo problema di cui nn riesco ad uscirne
fuori:
devo usare BeginThread e passare alla funzione chiamata un parametro che
in realtà è una STRUTTURA definita cosi
type TConnessioni = record
    NOME        : string[30]
    IP          : string[15];
    PORTA       : string[5];
    DEVICE      : TTcpSrvClient; //WSocket di FPiette
  end;
ho dichiarato in una sezione ThreadVar la variabile:
ThreadVar
  msgPtr : ^TConnessioni;
la funzione del Thread è:
function ConnettiSubThread(PARAMETERS : pointer) : integer;
begin
   msgPtr := PARAMETERS;
 
MessageBox(pchar(msgPtr^.IP+'|'+msgPtr^.PORTA),pchar('titolo'),MB_ICONASTERISK+MB_OK);
   EndThread(0);
end;
funzione che crea il Thread:
procedure PIPPO(Param : TConnessioni);
var ThreadId,ThreadHandle : integer;
begin
  ThreadHandle := BeginThread(nil,0,addr(ConnettiSubThread),addr
(Param),0,ThreadId);
end;
chiamo la funzione che crea il Thread in questo modo:
[...]
var variabile_    : TConnessioni;
begin
variabile_.IP     := '127.0.0.1';
variabile_.PORTA  := '5000';
variabile_.NOME   := 'TEST';
variabile_.DEVICE := ListView1; //un componente grafico sul Form1
PIPPO(variabile_);
end;
a questo punto quando il programma processa l'inizio del Thread, mi
vengono invertiti alcune volte l'IP con la PORTA, mentre altre volte mi
compaiono pezzi di codice delphi oppure nomi di label di altri programmi
attualmente attivi (del tipo "&File", "&Modifica, oppure "Borland Delphi
7") oppure ancora caratteri a caso....
possibile che non si possa passare una struttura ad un thread?
sto diventando matto..ho provato CDECL e STDCALL ma mi crasha il Thread
appena converto il <PARAMETER : pointer> nel <TConnessioni>
Fino al <BeginThread> la variabile <Param> è corretta, dentro nel Thread
e' tutto sballato.
help
grazie 1000
--- posted by geoForum on 
http://www.delphiedintorni.it

 variabile_.DEVICE := ListView1; //un componente grafico sul Form1
                        ^^^^^^^^^
prima dici che device è un wsocket e poi assegni una listview.
A parte cio, un tentativo da fare sarebbe cambiare il prototipo della 
funzione pippo, in modo che abbia come parametro un pointer ad una var 
di tpo TConnessioni.
Infine, hai motivi particolari per non usare la classe TThread?
-- 
Alberto Salvati
A NEAPOLITAN Delphi Developer who is studying c# and .net
"Dicette 'o pappece 'nfaccia 'a noce dammi 'o tiempo che pure te spertoso"

Si, mi scuso per l'errore di DEVICE...quello ke ho riportato è un 
estratto di del codice e ho omesso alcuni parametri (tanto sono INTEGER, 
STRING uguli agli altri).
Provero' ad usare un pointer anche per richiamare la funzione PIPPO.
Ma io mi chiedo: se per passare i parametri devo usare un puntatore ad 
una  Variabile_Globale, a che mi serve il puntatore? utilizzo 
direttamente la variabile globale. Il fatto è che il programma è un 
ServerSocket che deve permettere esecuzioni della funzione PIPPO a piu' 
utenti, e quidni una variabile globale nn va piu' bene perchè i dati 
verrebero condivisi da due funzioni che utilizzano in realtà dati diversi.


 verrebero condivisi da due funzioni che utilizzano in realtà dati diversi.
facciamo un po di ordine..
da qualche parte devi richiamare la funzione pippo che accetta come 
parametro una variabile di tipo x:
function Tqualcosa.FaiQuelloCheServeAdesso: integer;
var
   MiaVar: x;
begin
   pippo(MiaVar);
end;
senza variabili globali.
E kekakkio! in un contesto oop e come se non bastasse, multithread 
usiamo le variabili globali? Anatema! ;)
Ma ribadisco la mia perplessità: xche non usi una istanza di una classe 
opportunamente ereditata da tthread?


 classe opportunamente ereditata da tthread?
La tua perplessità è anche la mia, Alberto ;-) Oltre al fatto di non
aver capito molto di cosa deve fare il nostro amico, mi chiedo per
quale motivo non usare la classe TThread che incapsula abbastanza bene
le funzionalità dei thread e risulta più semplice da usare.
Emandt, prova a descrivere quello che devi fare in maniera più lineare
affinché ti si possa dare delle indicazioni.
IMHO, convertirei la struttura in una classe.
Ciao
guastatore

ho usato TThread e sembra funzionare...
pero' mi rode......Lavoro in Delphi da un casino di anni, e in veramente
pochi casi mi ha veramente mandato in delirio....
quando fa cosě: nn lo amo piu', e vorrei tornare a QBasic  ^__^
CMQ grazie 1000
-emandt-


 quando fa così: nn lo amo piu', e vorrei tornare a QBasic  ^__^
Noooo QB no :-)) A parte gli scherzi alcune classi Delphi hanno lo
specifico compito di alleviare la complessità di utilizzo delle API,
anche se a volte ricorrere a queste ultime è fondamentale.
TThread è una di queste ed il suo utilizzo è sempre consigliato.
Ciao
guastatore

effettivamente TThread supporta i parametri, ma un WHILE infinito dentro 
il TThread (in cui uso una DLL-Blocking che si interfaccia ad una porta 
COM) mi fa piantare l'IDE grafico della mia applicazione, mentre con 
BeginThread() questo non avviene...
questo mi fa pensare che siano due cose diverse il tThread e 
BeginThread...
FOrse tornero' al buon vecchio beginThread....
:(


 FOrse tornero' al buon vecchio beginThread....
TThread non fa altro che incapsulare le API di gestione dei thread
(oltretutto in modo cross-platform, per quanto questo possa avere ancora
senso con Delphi), solo che a differenza di te, le usa bene ;-)
Perchè non posti _un pezzo_ del tuo codice ?
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

TThread:
procedure TConnetti.Execute;
begin
  Form1.ConnettiSubThread;
  Form1.Memoria.ThreadCONNECT.Terminate;
end;
(dove "Form1.Memoria" č un RECORD contenente una variabile 
chiamata "ThreadCONNECT")
("ConnettiSubThread" esegue la funzione BLOCKING della DLL che chiamo)
per chiamare il TThread:
[..]
if (not Assigned(Form1.Memoria.ThreadCONNECT)) then 
Form1.Memoria.ThreadCONNECT := TConnetti.Create(true);
Form1.Memoria.ThreadCONNECT.DatiMezzoCorrente  := DatiMezzoCorrente;
Form1.Memoria.ThreadCONNECT.Resume;
[..]
ora il problema č: se nn avvio il Thread, posso chiudere normalmente il 
programma...se lo avvio e poi eseguo Application.Terminate (dato ke 
l'evento OnClose() sel Form1 fa solo ridurre a icona il programma) mi da 
un errore "SOEError 1400 : Invalid Window Handle"...
grrrr che nervoso!!
