Newsgroup: it.comp.lang.c++
Titolo: Problema con ActiveX

Sto scrivendo, per esperimento, un controllo ActiveX il cui scopo é quello
di leggere una porta ( in Windows 95) ogni 100 ms e di lanciare un
FireMioEventoVerificato
non appena legge dalla porta un certo valore;
Nel costruttore del controllo vorrei creare una thread con _beginthread ma
non riesco a passare il parametro del puntatore alla funzione che implementa
la thread che ovviamente ho dichiarato (public) come membro della
CControllo;
Il compilatore VC5 mi dice che l' errore é di type cast nel senso che non
può effettuare la conversione
da
void ( CControllo:: *)( class CControllo * )
a
void ( __cdecl *)( void * )
Sarei grato a chi volesse suggerire una soluzione.
Matteo

void ( __cdecl *)( void * )
ActiveX non c'entra -- il punto e` che _beginthread prende un puntatore
a una _funzione_ (che prende come argomento un void* e non torna
alcun risultato), mentre tu stai apparentemente cercando di passargli
un _metodo_ della classe CControllo (che oltretutto prende come
argomento un puntatore a CControllo, non un puntatore a void).  Tu,
quindi, devi passare a _beginthread() appunto questo, l'indirizzo di
una funzione siffatta.
Il void* che viene poi passato a quella funzione e` cio` che tu a tua
volta hai passato a _beginthread come terzo argomento (il secondo,
lo stacksize del thread, normalmente si passa a 0, cosi` che le cose
si "adattino da sole").
Devi quindi incapsulare le cose in modo che quella funzione e quel
void* facciano appunto quello che tu desideri.
Supponi, ad esempio, che tu abbia una classe...:
class Controllo {
    // varia roba, e poi:
public:
    void pippo();
};
e una variabile
    Controllo cc;
e quel che vorresti far eseguire nel thread
(thread interamente contenuto nel lifetime
della variabile cc, naturalmente) e`:
    cc.pippo()
Questo puoi ottenerlo, ad esempio, avendo
una funzione globale di questo tipo:
void callpippo(void *pControl)
{
    reinterpret_cast<Controllo*>(pControl)
        ->pippo();
}
e chiamando _beginthread cosi`:
    _beginthread(callpippo, 0, &cc);
Si possono fare anche cose assai piu`
complicate e ricche, con sfiziosissimi
template e quant'altro, ma la funzionalita`
base e` questa.
Alex

Nel costruttore del controllo vorrei creare una thread con _beginthread ma
Ho gia` risposto nel dettaglio, ma, ripensandoci, c'e` un fattore
fondamentale che puo` non essere chiaro (dalla documentazione in
linea Microsoft non lo e` affatto...):
	_beginthread NON va usata!!!
O, almeno, praticamente mai.  _beginthreadex e` meglio; buona prassi
dunque prendere l'abitudine di usare quella (unica differenza che
qui puo` essere rilevante e` che la funzione da passare alla
beginthreadex dev'essere tipo WINAPI, cioe` __stdcall).  beginthread
chiude l'handle del thread stesso che ha appena fatto partire pur
ritornando l'handle stessa (chiusa o meno a seconda della fortuna
e delle condizioni di corsa...), un pastrocchio assurdo.
Forse ancora piu` importante: ne` beginthreadex, ne` a maggior
ragione beginthread, vanno MAI usate se il nostro programma usa
le MFC!!!  ***MAI***.  Usare invece AfxBeginThread (o altre forme
d'uso della classe CWinThread)...!
Alex
--
 ____    Alex Martelli, Bologna, Italia -- email: 
al...@magenta.com
 \SM/___                                 
http://magenta.com/~alex
  \/\bi/     You never know what is enough unless you know what
     \/          is more than enough.