Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - HANDLE a thread non validi all'esterno di una funzione
Forum - C/C++ - HANDLE a thread non validi all'esterno di una funzione

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 20:48
Sabato, 27/02/2010
Ciao a tutti. Dato il codice sottostante

Codice sorgente - presumibilmente C#

  1. HANDLE hThread;
  2. void sendAsynchronousMessage(TCHAR title[], TCHAR text[], int type) {
  3.    DWORD dwThreadId;
  4.    //Params è una struct creata da me
  5.    Params params = {(TCHAR*)title,(TCHAR*)text, &type};
  6.    hThread = CreateThread(
  7.       NULL,
  8.       0,
  9.       (LPTHREAD_START_ROUTINE)&sendMessage,
  10.       ¶ms,
  11.       0,
  12.       &dwThreadId);
  13. }



Mi sapreste dire perchè la variabile globale hThread dopo aver lanciato la funzione sendAsynchronousMessage non è più valida?
Dovrei praticamente far ritornare a questa funzione un HANDLE al thread lanciato(anzichè metterlo come variabile globale) ma una volta invocata alla riga di codice successiva l'handle non funziona più

P.S.: il codice sorgente non è C#, perchè cavolo è scritto così sopra il codice?

Ultima modifica effettuata da robrock80 il 27/02/2010 alle 21:02


Nel mondo ci sono 10 tipi di persone: quelle che capiscono il binario e quelle che non lo capiscono
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 21:32
Sabato, 27/02/2010
Testo quotato

Postato originariamente da robrock80:
Mi sapreste dire perchè la variabile globale hThread dopo aver lanciato la funzione sendAsynchronousMessage non è più valida?



Se è globale, come fa a non essere valida? Che dici?

Testo quotato

Dovrei praticamente far ritornare a questa funzione un HANDLE al thread lanciato(anzichè metterlo come variabile globale) ma una volta invocata alla riga di codice successiva l'handle non funziona più



Se la funzione è

HANDLE sendAsynchronousMessage ...  

allora sarà

return(CreateThread .... );

( In che senso "non funziona piu'"? )

Testo quotato

P.S.: il codice sorgente non è C#, perchè cavolo è scritto così sopra il codice?



Non ti preoccupare ... è un problema del forum ...

Ultima modifica effettuata da nessuno il 27/02/2010 alle 21:34


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 21:42
Sabato, 27/02/2010
Dopo aver invocato la funzione sendAsynchronousMessage invoco la funzione WaitForSingleObject passandogli l'Handle e praticamente il processo esplode. se invece la funzione WaitForSingleObject la invoco all'interno di sendAsynchronousMessage subito dopo aver creato il thread tutto funziona. Per adesso ho creato una variabile globale giusto per fare le prove visto che con una variabile ritornata non mi funziona: sembra che Windows invalidi gli Handle ai thread automaticamente quando si esce dalla funzione

Ultima modifica effettuata da robrock80 il 27/02/2010 alle 21:42


Nel mondo ci sono 10 tipi di persone: quelle che capiscono il binario e quelle che non lo capiscono
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 21:55
Sabato, 27/02/2010
Se mostri il codice che hai scritto senza variabile globale, compresa la WaitForSingleObject, si capisce meglio ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 22:10
Sabato, 27/02/2010
Ok, ho estratto una parte di codice dal mio programma e ho creato questo:

Codice sorgente - presumibilmente C++

  1. #include <windows.h>
  2. #include <tchar.h>
  3.  
  4. //TODO: Sostituire variabili con array di puntatori
  5. typedef struct _Params {
  6.                 void *param_01, *param_02, *param_03,
  7.                         *param_04, *param_05, *param_06;
  8.                 void (*function_00)(struct _Params *),
  9.                         (*function_01)(struct _Params *),
  10.                         (*function_02)(struct _Params *),
  11.                         (*function_03)(struct _Params *),
  12.                         (*function_04)(struct _Params *),
  13.                         (*function_05)(struct _Params *),
  14.                         (*function_06)(struct _Params *),
  15.                         (*function_07)(struct _Params *),
  16.                         (*function_08)(struct _Params *),
  17.                         (*function_09)(struct _Params *);
  18.                 void *return_01;
  19.         } Params;
  20.  
  21.  
  22. HANDLE sendAsynchronousMessage(TCHAR [], TCHAR[], int);
  23. DWORD sendMessage(LPVOID);
  24.  
  25.  
  26. HANDLE sendAsynchronousMessage(TCHAR title[], TCHAR text[], int type) {
  27.         DWORD dwThreadId;
  28.         HANDLE hThread = malloc(sizeof(HANDLE));
  29.         Params params = {(TCHAR*)title,(TCHAR*)text, &type};
  30.         hThread = CreateThread(
  31.                                         NULL,  
  32.                                         0,             
  33.                                         (LPTHREAD_START_ROUTINE)&sendMessage,
  34.                                         &params,
  35.                                         0,              //Lancia il Thread immediatamente
  36.                                         &dwThreadId);
  37.         return hThread;
  38. }
  39.  
  40.  
  41. DWORD sendMessage(LPVOID param) {
  42.         Params* params = (Params*)param;
  43.         MessageBox( NULL, (TCHAR*)params->param_02, (TCHAR*)params->param_01, *(int*)params->param_03);
  44.         return 0;
  45. }
  46.  
  47.  
  48. int WINAPI WinMain(HINSTANCE hInstance,
  49.                      HINSTANCE hPrevInstance,
  50.                      LPSTR     lpCmdLine,
  51.                      int       nCmdShow){
  52.  
  53.         HANDLE hThread = sendAsynchronousMessage("Titolo MBx", "Testo MBX", MB_OK);
  54.         WaitForSingleObject(hThread, 10000);
  55.         CloseHandle(hThread);
  56.         free(hThread);
  57.         return 0;
  58. }




Copialo e incollalo sul tuo tool di sviluppo e dimmi se ti sputa fuori Windows quando lanci il processo

Ultima modifica effettuata da robrock80 il 27/02/2010 alle 22:12


Nel mondo ci sono 10 tipi di persone: quelle che capiscono il binario e quelle che non lo capiscono
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 22:13
Sabato, 27/02/2010
Perdonami ... ma non avevi detto che "allocavi" l'handle utilizzandolo come se fosse un puntatore ... ecco perchè non capivo.

L'handle è un numero, non un puntatore ... devi restituirlo semplicemente al chiamante ...

In pratica la funzione deve essere

Codice sorgente - presumibilmente C#

  1. HANDLE sendAsynchronousMessage(TCHAR title[], TCHAR text[], int type) {
  2.     DWORD dwThreadId;
  3.     Params params = {(TCHAR*)title,(TCHAR*)text, &type};
  4.     return (CreateThread(
  5.                     NULL,    
  6.                     0,        
  7.                     (LPTHREAD_START_ROUTINE)&sendMessage,
  8.                     ¶ms,
  9.                     0,        //Lancia il Thread immediatamente
  10.                     &dwThreadId) );
  11. }



Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 22:21
Sabato, 27/02/2010
Prima di provare con la variabile globale ho provato anche come hai detto te, ma niente, non ne vuole proprio sapere: sono convinto che Windows invalidi gli HANDLE quando si esce dalle funzioni in cui sono stati creati


Nel mondo ci sono 10 tipi di persone: quelle che capiscono il binario e quelle che non lo capiscono
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 22:37
Sabato, 27/02/2010
Ovviamente devi eliminare quella free che non ha senso ...

Per il resto, funziona ...

Testo quotato


sono convinto che Windows invalidi gli HANDLE quando si esce dalle funzioni in cui sono stati creati



Ma neanche per sogno ...


Ultima modifica effettuata da nessuno il 27/02/2010 alle 22:50


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
robrock80 (Normal User)
Pro


Messaggi: 143
Iscritto: 11/12/2006

Segnala al moderatore
Postato alle 20:03
Domenica, 28/02/2010
Certo che il free ha senso: la memoria l'ho allocata all'interno della funzione e a me chi garantisce che la funzione CloseHandle contrassegna la memoria come riallocabile?
Comunque non è questo il problema, perchè se richiamo la funzione di Wait dentro la sendAsynchronousMessage, il programma non dà problemi.
Ho copiato e incollato la funzione come l'hai scritta te, ma niente, il processo esplode ancora.
Sarà un problema del compilatore? (Io uso MinGW)

Ultima modifica effettuata da robrock80 il 28/02/2010 alle 20:13


Nel mondo ci sono 10 tipi di persone: quelle che capiscono il binario e quelle che non lo capiscono
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo