Newsgroup: it.comp.programmare.win32
Titolo: Visual Studio 6 e threads - error C2665: 'AfxBeginThread'

Bene, sono di nuovo a scrivere per un altro problema per cui non riesco a
trovare la soluzione.
La funzione  'AfxBeginThread'  mi dovrebbe consentire di far partire un
thread, passando come argomenti la funzione main del thread, un puntatore ad
un oggetto con cui voglio che il thread colloqui e la priorità.
Io ho fatto così:
m_pManagerThread = AfxBeginThread(m_pMan.run, (LPVOID)&dataProc, iPriority);
e la funzione run ha questa interfaccia:
UINT Manager::run(LPVOID pParam)
In un'altra applicazione questo sistema *funziona alla grande*, ma questa
volta ricevo il seguente errore:
error C2665: 'AfxBeginThread' : none of the 2 overloads can convert
parameter 1 from type 'unsigned int (void *)'
Non so come ovviare al problema!
C'è qualcuno che mi può aiutare?
Se c'è lo ringrazio tanto!
Luca

Ciao, Luca!
Il giorno 23/11/2003 alle ore 23:43 hai scritto:
 L> error C2665: 'AfxBeginThread' : none of the 2 overloads can convert
 L> parameter 1 from type 'unsigned int (void *)'
Hai dichiarato la funzione run statica ?
Bye

 Hai dichiarato la funzione run statica ?
Ora l'ho dichiarata statica e funziona. Ma perché non funziona se non č
statica?
Un'altra cosa, cosě mi togli il dubbio. :-)
Definendo una variabile var di tipo MyClass1 nell'header di un'altra Classe
MyClass2
private:
    MyClass1 var;
e tentando di utilizzare tale variabile nell'implementazione della classe
MyClass2
var.method1();
ottengo i seguenti errori:
error C2146: syntax error : missing ';' before identifier 'var'
error C2501: 'MyClass1':  missing storage-class or type specifiers
error C2501: 'var':  missing storage-class or type specifiers
Eppure ho incluso l'header della classe MyClass1.
Com'č che si generano questi errori?
Non sono un esperto del Visual C++, ma me lo ricordavo meno ostico. :-(
Mi puoi aiutare?
Luca

Ciao, Luca!
Il giorno 24/11/2003 alle ore 23:06 hai scritto:
 L> Ora l'ho dichiarata statica e funziona. Ma perché non funziona se non è
 L> statica?
Per l'indirizzamento.
 L> error C2146: syntax error : missing ';' before identifier 'var'
 L> error C2501: 'MyClass1':  missing storage-class or type specifiers
 L> error C2501: 'var':  missing storage-class or type specifiers
 L>
 L> Eppure ho incluso l'header della classe MyClass1.
Ne sei sicuro ? Gli errori mi sembrano dovuti o a errori di sintassi (magari
manca un punto e virgola da qualche parte) o alla mancata visibilita' della
classe.
Bye

 visibilita' della classe.
Ho capito meglio cosa accade:
Tu hai 2 classi: "CTavolo" e "CSedia".
Vuoi che ciascuna delle due possa gestire un oggetto dell'altra, oppure un
puntatore all'oggetto, non importa.
Allora, in ciascun header dichiarerai una variabile dell'altra classe:
in Tavolo.h
CSedia sedia1;
in Sedia.h
CTavolo tavolo1;
e in ciascun .cpp e/o .h includerai l'header per riconoscere l'oggetto
dichiarato:
in Tavolo.cpp e/o Tavolo.h
#include "sedia.h"
in Sedia.cpp e/o Sedia.h
#include "tavolo.h"
Direi che ho provato tutte le combinazioni di inserimento e anche usando
puntatori alle due classi, ma niente da fare.
Se questo procedimento lo faccio solo per una classe (dichiarando, ad
esempio, tavolo1 in Sedia.h) funziona tutto, compila tutto. Se invece lo
faccio in tutte e due, incrociando quindi i riferimenti alle classi, si
incasina e nella compilazione mi dà i problemi di cui sopra.
E' una cosa all'apparenza banale, ma io che non sono un esperto, non so come
fare per fare in modo che tutte le due classi possano avere due variabili
globali per accedere a ciascun oggetto.
Consigli sono ben accetti!!!
Grazie
Luca

Ciao, Luca!
Il giorno 25/11/2003 alle ore 21:47 hai scritto:
 >> Per l'indirizzamento.
 L>
 L> E quindi?
E quindi se non la dichiari static in C++ non funziona.
 L> e in ciascun .cpp e/o .h includerai l'header per riconoscere l'oggetto
 L> dichiarato:
 L>
 L> in Tavolo.cpp e/o Tavolo.h
 L> #include "sedia.h"
 L>
 L> in Sedia.cpp e/o Sedia.h
 L> #include "tavolo.h"
[...]
 L> Se questo procedimento lo faccio solo per una classe (dichiarando, ad
 L> esempio, tavolo1 in Sedia.h) funziona tutto, compila tutto. Se invece lo
 L> faccio in tutte e due, incrociando quindi i riferimenti alle classi, si
 L> incasina e nella compilazione mi dà i problemi di cui sopra.
Adesso ho capito. Negli header dichiara solo le classi e non includere
l'header dell'altra classe (altrimenti fa un casino che non te lo immagini
nemmeno), in cima a sedia.h inserisci una riga come questa:
class CTavolo;
idem in tavolo.h inserisci una riga class CSedia; e vedrai che andra' tutto
a posto. Ovviamente nei cpp dovrai includere entrambi gli header e inserisci
anche degli #ifndef per evitare di dichiarare due volte le stesse classi.
Bye

 volte le stesse classi.
Ok, ho fatto come hai detto e compilava. Poi, nell'esecuzione mi dava errori
di Access Violation in alcune variabili, come una di tipo BOOL. Errori per
me inspiegabili. Allora ho dichiarato semplicemente i due oggetti nei file
.cpp e non ho toccato gli header. Compila ed esegue, MA!
Ma c'č un ma... 8-O
Ora all'esecuzione compare questo messaggio: "Debug Asserion Failed" sul
file afxwin1.inl (linea 22). E' un errore della debug library. Qua mi fermo.
Non mi č mai capitato di avere cosě tanti errori nelle varie fasi di
sviluppo.
Cosa diavolo c'č che non va ora?
Grazie per la tua pazienza! :-)
Luca

Ciao, Luca!
Il giorno 26/11/2003 alle ore 23:34 hai scritto:
 L> Ora all'esecuzione compare questo messaggio: "Debug Asserion Failed" sul
 L> file afxwin1.inl (linea 22). E' un errore della debug library. Qua mi
 L> fermo. Non mi č mai capitato di avere cosě tanti errori nelle varie fasi
 L> di sviluppo.
 L> Cosa diavolo c'č che non va ora?
Da quello che mi risulta e' un assert della macro AfxGetResourceHandle().
Io ti consiglierei di rivedere il progetto dall'inizio o comunque di
razionalizzare meglio le classi (soprattutto cerca di togliere i riferimenti
incrociati).
Bye

 incrociati).
I riferimenti incrociati li devo lasciare per forza; deve funzionare così e
non vedo cosa ci sia di male. Ora utilizzo dei puntatori ad oggetti (di cui
uno è nell'heap).
Il problema si è spostato nella chiamata di un metodo nella classe della
Dialog Box: UpdateData(FALSE).
Un oggetto esterno quindi chiama:
dlg->functionUpdate()
e dentro functionUpdate() viene chiamata
UpdateData(FALSE)
Il metodo che invoca UpdateData(FALSE) è invocato quindi da un oggetto
esterno, che punta alla dialog tramite dlg* e su UpdateData si verifica
sempre il "Debug Assertion Failed", questa volta sul wincore.cpp, linea 884,
nella chiamata di AssertValid per la dialog, suppongo.
Se chiamo invece UpdateData da una funzione invocata dalla classe stessa
(cioè la dialog) tutto funziona regolarmente. Peccato che l'Update della
grafica debba essere fatto ad eventi esterni, nel modo in cui serve a me.
Ma perché non andrebbe bene in questo modo?

Ciao, Luca!
Il giorno 27/11/2003 alle ore 22:25 hai scritto:
 L> Se chiamo invece UpdateData da una funzione invocata dalla classe stessa
 L> (cioč la dialog) tutto funziona regolarmente. Peccato che l'Update della
 L> grafica debba essere fatto ad eventi esterni, nel modo in cui serve a
 L> me.
A questo punto mi dispiace ma non credo di poterti aiutare molto,
bisognerebbe vedere tutto il contesto.
 L> Ma perché non andrebbe bene in questo modo?
Non e' che non va bene e' che quando cominciano a verificarsi errori
apparentemente incomprensibili, da cui non si riesce a venirne fuori, per
me, e' meglio ricominciare da capo.
Bye

 per me, e' meglio ricominciare da capo.
No, no. Il progetto va bene. Ma c'è un particolare che non ti ho detto e che
ho scoperto essere la causa dell'errore.
L'aaplicazione è multithread! :-)
Ergo ho trovato questi commenti:
  // Note: if either of the above asserts fire and you are
  // writing a multithreaded application, it is likely that
  // you have passed a C++ object from one thread to another
  // and have used that object in a way that was not intended.
  // (only simple inline wrapper functions should be used)
  //
  // In general, CWnd objects should be passed by HWND from
  // one thread to another.  The receiving thread can wrap
  // the HWND with a CWnd object by using CWnd::FromHandle.
  //
  // It is dangerous to pass C++ objects from one thread to
  // another, unless the objects are designed to be used in
  // such a manner
Adesso inierò a documentarmi su come passare l'oggetto dialog tra un thread
e un altro. Tu, se hai dei consigli mi faranno molto piacere.
Grazie ancora!
Ciao