View Full Version : callback in c++...si puo?
gestione della porta seriale:
l'ho implementata in c tramite la sigaction SIGIO.
cioe' quando arriva qualche byte nel mio descrittore "fd" mi viene chiamata una callback.
che puo' leggere i byte in questione.
stavo cercando di portare in c++ questo modello.
in c la callback che mi gestisce la seriale si chiama
void signal_handler_io(int status);
quando riempio la struttura sigaction per indicare questa callback faccio:
saio.sa_handler= signal_handler_io;
ora la mia funzione membro in cpp e'
Myir::signal_handler_io(int status);
e se faccio
saio.sa_handler= Myir::signal_handler_io;
mi da un errore:
/\/\@®¢Ø
23-07-2004, 19:46
Originariamente inviato da x110
gestione della porta seriale:
l'ho implementata in c tramite la sigaction SIGIO.
cioe' quando arriva qualche byte nel mio descrittore "fd" mi viene chiamata una callback.
che puo' leggere i byte in questione.
stavo cercando di portare in c++ questo modello.
in c la callback che mi gestisce la seriale si chiama
void signal_handler_io(int status);
quando riempio la struttura sigaction per indicare questa callback faccio:
saio.sa_handler= signal_handler_io;
ora la mia funzione membro in cpp e'
Myir::signal_handler_io(int status);
e se faccio
saio.sa_handler= Myir::signal_handler_io;
mi da un errore:
E' membro statico o normale ? Nel secondo caso ricordati che devi specificare l'istanza alla quale riferirsi, ad esempio
Myir x(...);
/* blah */
saio.sa_handler = & x.signal_handler_io
Black imp
24-07-2004, 03:19
Originariamente inviato da x110
gestione della porta seriale:
l'ho implementata in c tramite la sigaction SIGIO.
cioe' quando arriva qualche byte nel mio descrittore "fd" mi viene chiamata una callback.
che puo' leggere i byte in questione.
stavo cercando di portare in c++ questo modello.
in c la callback che mi gestisce la seriale si chiama
void signal_handler_io(int status);
quando riempio la struttura sigaction per indicare questa callback faccio:
saio.sa_handler= signal_handler_io;
ora la mia funzione membro in cpp e'
Myir::signal_handler_io(int status);
e se faccio
saio.sa_handler= Myir::signal_handler_io;
mi da un errore:
stai chiamando la funzione membro senza un oggetto che istanzi la classe.
ad as dichiari 'a' puntatore un oggetto della classe, poi istanzi l'oggetto con una new e infine chiamerai la funzione:
saio.sa_handler=a->signal_handler_io(...);
tra l'altro nel tuo esempio hai dichiarato la funzione in modo che debba accettare un parametro ma tu non le passi niente
rispondendo a /\/\@®¢Ø non voglio creare un oggetto e dalla main assegnarci una funzione
ma gia' da dentro la classe voglio che la stessa classe di default abbia una propia
funzione di callback che poi e' il cuore della classe, altrimenti il modello ad oggetti
va in c@@o.;)
tra l'altro nel tuo esempio hai dichiarato la funzione in modo che debba accettare un parametro ma tu non le passi niente
se le passassi qualcosa chiamerei la funzione () invece senza passargli niente dico
qual'e' l'indirizzo della funzione di callback da chiamare
io voglio una classe autonoma che punti da se ad una funzione sua di callback senza
che debba essere specificata dopo la sua creazione ma che sia implicita.
forse this potrebbe aiutarmi?
/\/\@®¢Ø
24-07-2004, 12:27
Originariamente inviato da x110
rispondendo a /\/\@®¢Ø non voglio creare un oggetto e dalla main assegnarci una funzione
ma gia' da dentro la classe voglio che la stessa classe di default abbia una propia
funzione di callback che poi e' il cuore della classe, altrimenti il modello ad oggetti
va in c@@o.;)
Se ho capito bene allora, quel che ti serve e' un metodo "di classe", cioe' da chiamare senza istanze.
Tale metodo allora deve essere 'marchiato' static.
Qualcosa del genere insomma:
class Myir {
/* ... */
static void Myir::signal_handler_io(int status);
/* ... */
};
/*...*/
saio.sa_handler= & Myir::signal_handler_io;
Black imp
24-07-2004, 12:28
ah quindi tu vuoi passare a saio.sa_handler l'indirizzo della funzione definita dentro la classe. allora la funzione nella classe deve essere static e saio.sa_handler deve essere un puntatore a funzione con la stessa intestazione.
ovviamente la funzione static non può accedere che ad elementi static della classe cioè non può per ovvie ragioni accedere ai dati di ciascun oggetto che istanzierai di quella classe. può accedere solo alle var static della classe poichè anche di quelle c'è una sola per classe. this non lo puoi proprio usare perchè le funzioni static non sono riferite ad alcun oggetto.
Black imp
24-07-2004, 12:29
sono arrivato in ritardo di un minuto :p
ho capito ma non molto bene.
il mio obiettivo e':
creare una classe che mi gestisca una porta infrarossi che altro non e' che una porta seriale.
voglio poter creare un oggetto, assegnargli una porta seriale e leggere e trasmettere dati da questo oggetto.
il modo in cui i dati arrivano all'oggetto e' tramite una funzione di callback che io vorrei
ridefinire per ogni oggetto al momento dell'inizializzazione dello stesso,
e non avere una sola callback per tutta la classe.
con static la funzione e' "di classe"
a me serve l'indirizzo della funzione di callback
appartenente "all'oggetto istanziato" a runtime per poterlo inserire nella var saio.sa_handler.
e' complesso ma in altro modo come si puo' fare?
Black imp
24-07-2004, 13:35
Originariamente inviato da x110
ho capito ma non molto bene.
il mio obiettivo e':
creare una classe che mi gestisca una porta infrarossi che altro non e' che una porta seriale.
voglio poter creare un oggetto, assegnargli una porta seriale e leggere e trasmettere dati da questo oggetto.
il modo in cui i dati arrivano all'oggetto e' tramite una funzione di callback che io vorrei
ridefinire per ogni oggetto al momento dell'inizializzazione dello stesso,
e non avere una sola callback per tutta la classe.
con static la funzione e' "di classe"
a me serve l'indirizzo della funzione di callback
appartenente "all'oggetto istanziato" a runtime per poterlo inserire nella var saio.sa_handler.
e' complesso ma in altro modo come si puo' fare?
non riesco a capire cosa non capisci :rolleyes:
:D
allora se hai una funzione di callback che deve accedere ai singoli dati dell'oggetto la sarà una normalissima funzione membro e DOPO aver istanziato l'oggetto passerai l'indirizzo della funzione come ti avevamo detto prima a saio.sa_handler.
non capisco perchè allora non ti andava bene la prima soluzione.
o al costruttore passi come parametro il puntatore di saio.sa_handler e nel costruttore gli assegni l'indirizzo della tua callback o fai una funzione aggiuntiva nella classe nella quale farai la stessa cosa. tra l'altro ricordati di metterla public questa funzone.
scusa se te lo chiedo - per capire quale può essere il dubbio - tu programmi in C++ da molto?
leggere un libro non basta...
programmo da 5/6 minuti
io ho un file che e' Myir.h
class Myir:public QObject{
Q_OBJECT
public:
Myir(QObject *parent=0,const char * name=0);
void signal_handler_IO(int signum);
int com_open;
private:
int apriporta(char *device);
void datidallaseriale(int messaggio,int valore);
int fd_com;
}
e poi c'e' Myir.cpp
Myir::Myir(QObject *parent, const char *name):QObject(parent,name){
//apri file di configurazione e leggi il device al quale collegare questo oggetto
apriporta(device);
}
void Myir::signal_handler_IO(int signum){
//gestione dei bytes presenti nella seriale.
}
Myir::apriporta(char *device){
struct sigaction saio;
saio.sa_handler=****************************************cosa ci metto qui?
sigaction(SIGIO,&saio,NULL);
}
il main lo tralascio perche' mi sembra semplice:confused:
se in saio.sa_handler=************************
ci metto&Myir::signal_handler_io l'errore e':
Myir.cpp:312 converting from 'void(Myir::*)(int)' to 'void (*)(int)'
Originariamente inviato da Black imp
allora se hai una funzione di callback che deve accedere ai singoli dati dell'oggetto la sarà una normalissima funzione membro e DOPO aver istanziato l'oggetto passerai l'indirizzo della funzione come ti avevamo detto prima a saio.sa_handler.
non capisco perchè allora non ti andava bene la prima soluzione.
voglio che saio sia una struttura dell'oggetto e non fuori dell'oggetto.
mentre cio' che mi dite e'
Myir x(...);
/* blah */
saio.sa_handler = & x.signal_handler_io
o al costruttore passi come parametro il puntatore di saio.sa_handler e nel costruttore gli assegni l'indirizzo della tua callback
o fai una funzione aggiuntiva nella classe nella quale farai la stessa cosa. tra l'altro ricordati di metterla public questa funzone.
prova a leggere il codice che ho postato.:)
Black imp
24-07-2004, 15:17
Originariamente inviato da x110
voglio che saio sia una struttura dell'oggetto e non fuori dell'oggetto.
mentre cio' che mi dite e'
Myir x(...);
/* blah */
saio.sa_handler = & x.signal_handler_io
prova a leggere il codice che ho postato.:)
aaaahh
cavolo ma all'inizio non era chiaro che l'assegnamento lo facessi dentro una funzione della classe!!
al posto degli asterischi:
ci metti semplicemente signal_handler_io e basta. al più metti davanti & ma non è necessario. l'errore infatti che ti dà è su Myir:: perchè sei già nello stesso scope. se metti Myir:: cerca in uno scope annidato che non c'è ;)
fammi sapere se è tutto ok dopo!
all'inizio pensavo cosi' anch'io, ma:
senza & mi da:
no matches converting function 'signal_handler_io' to type 'void (*) (int)'
candidates are void Myir::signal_handler_io(int)
con &
taking the address of a non-static member function
to form a pointer to member function, say '&Myir::signal_handler_IO'
converting from 'void (Myir::*)(int)' to 'void (*)(int)'
Originariamente inviato da Black imp
al posto degli asterischi:
ci metti semplicemente signal_handler_io e basta. al più metti davanti & ma non è necessario. l'errore infatti che ti dà è su Myir:: perchè sei già nello stesso scope. se metti Myir:: cerca in uno scope annidato che non c'è ;)
non va lo stesso perché l'handler non può essere una funzione membro non statica, in quanto le funzioni membro hanno come primo parametro implicito un riferimento all'oggetto di appartenenza, per cui il prototipo delle due funzioni non corrisponde
Black imp
24-07-2004, 15:42
Originariamente inviato da pela
non va lo stesso perché l'handler non può essere una funzione membro non statica, in quanto le funzioni membro hanno come primo parametro implicito un riferimento all'oggetto di appartenenza, per cui il prototipo delle due funzioni non corrisponde
quindi non si può assegnare a un puntatore a funzione esterno alla classe una funzione membro non statica della classe?
e con un cast?
quindi dici che non esiste soluzione?
se cosi' fosse e' un po un sistema del c......
non si puo' fare un cast?:confused: :rolleyes:
this potrebbe essere utile?
sorpassato per un microsecondo:cry:
Black imp
24-07-2004, 15:48
Originariamente inviato da x110
quindi dici che non esiste soluzione?
se cosi' fosse e' un po un sistema del c......
non si puo' fare un cast?:confused: :rolleyes:
this potrebbe essere utile?
scrivere this.funzionemembro o funzionemembro è lo stesso :(
ma scusa non ho capito però il senso: saio.sa_handler non gestisce mica una sola porta? se è così perchè fare una classe istanziabile da più oggetti ciascuno con la sua funzione di callback?
scusa è un po' che non uso il c++ e sto cercando di capirti
Originariamente inviato da Black imp
scrivere this.funzionemembro o funzionemembro è lo stesso :(
ma scusa non ho capito però il senso: saio.sa_handler non gestisce mica una sola porta? se è così perchè fare una classe istanziabile da più oggetti ciascuno con la sua funzione di callback?
scusa è un po' che non uso il c++ e sto cercando di capirti
ma credo di no,
sinceramente non conosco al 100% i segnali,
ora studio meglio cio' che ho scopiazzato per ricevere il segnale.
comunque il senso e':
poter aprire piu' porte infrarossi a cui fanno capo piu' oggetti
istanziati della stessa classe con piu' funzioni di callback appartenenti a ciascun oggetto
Black imp
24-07-2004, 16:07
Originariamente inviato da x110
comunque il senso e':
poter aprire piu' porte infrarossi a cui fanno capo piu' oggetti
istanziati della stessa classe con piu' funzioni di callback appartenenti a ciascun oggetto
ok ma la saio.sa_handler ne gestisce una sola giusto? - non è una domanda retorica perchè proprio non lo so -
se così fosse non avrebbe senso avere più callback anche perchè ogni callback fa la stessa operazione; potrebbe però accedere ai dati specifici di ciascuna istanza ok ma se le istanze fanno capo a una sola infrarossi che prevede una sola funzione di callback che senso ha fare una classe? abbi pazienza, dopo potrei esserti più d'aiuto
cioè mi spiego se tu hai più porte infrarossi avrai anche più handler giusto? qui ne hai uno solo o sbaglio? quindi non ha senso istanziare più oggetti per una sola porta. o no?
si ma proprio non lo so neanche io sto leggendo a proposito info sui signal.
il fatto e' :se ho 2 porte infrarossi e voglio leggere da tutte e due uso 2 oggetti.
quindi la necessita' ci puo' essere anche di 2 callback separate una per ogni oggetto.
c'e' da vedere se la sigaction lo permette.
ciao e grazie.;)
istanziare piu' oggetti per una porta comunque non ha senso.
per piu' porte si.
leggendo la documentazione sembra che si possa gestire una sola funzione di callback
pero' questa forse ti dice chi(quale descrittore) ha generato il segnale...
ora leggo meglio
c'e' solo una funzione di callback
mi sa che usero' il primo modo che mi avete indicato.
o forse e' meglio usare la static?
comunque in c++ non si possono gestire agevolmente le callback.
o forse e' solo ignoranza.
:cry: :cry: :cry:
se avete altre idee....
Black imp
25-07-2004, 03:12
vedi se tu hai una sola callback per porta come è logico non ha senso fare una classe per porta e neanche una per tutte le porte perchè:
nel primo caso creeresti la possibilità di più oggetti tutti legati alla stessa porta e che quindi condividono la stessa callback. in questo caso la callback sarebbe un membro static ma che senso ha avere oggetti diversi per una sola callback?
nel secondo caso avresti una classe in cui ogni oggetto istanziato è legato ad una porta diversa. questo ha più senso ma quando scrivi la classe come fai a sapere a priori tutte le funzioni di callback diverse di cui potrai aver bisogno in base al momento?
la prima soluzione che mi viene in mente è di dichiarare una funzione friend.
ma ti chiedo: ok hai un oggetto per porta e quindi una callback diversa per porta. dove e come le scrivi le diverse callback??
Black imp
25-07-2004, 03:13
Originariamente inviato da x110
c'e' solo una funzione di callback
mi sa che usero' il primo modo che mi avete indicato.
o forse e' meglio usare la static?
comunque in c++ non si possono gestire agevolmente le callback.
o forse e' solo ignoranza.
:cry: :cry: :cry:
se avete altre idee....
il C è molto agevole per maneggiare l'hw. io non ho molta esperienza ma posso dire che effettivamente interfacciare una buona struttura a classi con delle librerie in C per la gestione dell'HW non è sempre agevolissimo
Black imp
25-07-2004, 03:22
Originariamente inviato da x110
si ma proprio non lo so neanche io sto leggendo a proposito info sui signal.
il fatto e' :se ho 2 porte infrarossi e voglio leggere da tutte e due uso 2 oggetti.
quindi la necessita' ci puo' essere anche di 2 callback separate una per ogni oggetto.
c'e' da vedere se la sigaction lo permette.
ciao e grazie.;)
allora che senso ha che apparengano alla stessa classe i due oggetti che devono avere 2 callback separate?
attenzione c'e' un problema.
io ho 1 una 1 callback e basta.
anche se apro 10 porte la callback rimane sempre una.
per colpa del sistema dei signal.
non e' il descrittore di file che dice quale callback chiamare ma e' la sigaction
che ha 1 sola callback per qualsiasi segnale di quel tipo(SIGIO).
non ho la possibilita' di dichiarare piu' callback per piu' porte.
quindi la modalita' a multiporta e' inattuabile con queste premesse.
cio che posso fare pero' e' la prima soluzione che mi avete detto.
istanziare un oggetto,
aprire la porta infrarossi
assegnare una funzione membro dell'oggetto come callback della struttura sigaction.
e cosi' dovrebbe funzionare.
se io aprissi un'altro processo pero' tutto cio' sarebbe gestibile, in quanto la sigaction
manderebbe il segnale al secondo processo con una seconda callback,con un secondo file descriptor.
certo cio' complica un bel po' la programmazione.
Black imp
27-07-2004, 02:02
Originariamente inviato da x110
attenzione c'e' un problema.
io ho 1 una 1 callback e basta.
anche se apro 10 porte la callback rimane sempre una.
per colpa del sistema dei signal.
non e' il descrittore di file che dice quale callback chiamare ma e' la sigaction
che ha 1 sola callback per qualsiasi segnale di quel tipo(SIGIO).
non ho la possibilita' di dichiarare piu' callback per piu' porte.
quindi la modalita' a multiporta e' inattuabile con queste premesse.
cio che posso fare pero' e' la prima soluzione che mi avete detto.
istanziare un oggetto,
aprire la porta infrarossi
assegnare una funzione membro dell'oggetto come callback della struttura sigaction.
e cosi' dovrebbe funzionare.
se io aprissi un'altro processo pero' tutto cio' sarebbe gestibile, in quanto la sigaction
manderebbe il segnale al secondo processo con una seconda callback,con un secondo file descriptor.
certo cio' complica un bel po' la programmazione.
ma veramente questa soluzione è proprio quella che non funzionava perchè il puntatore della funzione membro è del tipo (void)(NomeClasse::*)(int)
mentre saiosalcavolo è del tipo (void)(*)(int) :D
cnque se anzichè cercare di aprire un nuovo processo usassi un thread sarebbe molto più veloce e leggero ma per me rimane una soluzione sporca. cavolo mi piacerebbe saperne di più sulla gestione della porta in C per capire come scrivere una classe che implementi la gestione porta. se vuoi mandarmi una descrizione della libreria c o l'header file mi faccio un'idea e forse riesco a darti qualche idea
cioe' non ho capito bene cosa ti serve.....
io apro semplicemente una porta ttySx che fa riferimento alla seriale
con termios setto velocita e impostazioni della porta seriale.
imposto il descrittore della porta in modo che generi sigio,
attivo una funzione di gestione dei signal con saio signhandler.
comunque ti allego i sorgenti cosi' come sono.
sto facendo un'applicazione QT embedded per pda.
ciao.
Black imp
28-07-2004, 02:35
invalido, corrotto :(
scusa ma lo zip non lo tengo ho solo il tar e il gz di linux
Myapp.cpp
#include <qwidget.h>
#include <qpushbutton.h>
#include <qfont.h>
#include <stdio.h>
#include <qvbox.h>
#include <qapplication.h>
#ifndef MYAPP_H
#include </mnt/card/sharp/Myapp.h>
#endif
#ifndef MYINCASSI_H
#include </mnt/card/sharp/Myincassi.h>
#endif
#ifndef SHARP_H
#include </mnt/card/sharp/sharp.h>
#endif
Myapp::Myapp(QWidget *parent,const char *name):QWidget(parent,name){
QWidget::WStyle_SysMenu| QWidget::WStyle_Title);//|| QWidget::WStyle_NoBorderEx);
QVBox *box=new QVBox (this);
char nome[100];
QWidget *d=QApplication::desktop();
sprintf(nome,"w=%d h=%d",d->width(),d->height());
box->resize(240,200);
QPushButton *p_locali=new QPushButton(nome,box);
bzero(nome,sizeof(nome));
QPushButton *p_incassi=new QPushButton("INCASSI",box);
QPushButton *p_comunicazione=new QPushButton("COMUNICAZIONE",box);
p_locali->setFont(QFont("Times",24,QFont::Bold));
p_incassi->setFont(QFont("Times",24,QFont::Bold));
p_comunicazione->setFont(QFont("Times",24,QFont::Bold));
QObject::connect(p_incassi,SIGNAL(clicked()),this,SLOT(openincassi()));
QObject::connect(p_comunicazione,SIGNAL(clicked()),qApp,SLOT(quit())); this->setGeometry(10,50,220,160);
};
void Myapp::openincassi(){
Myincassi *INCASSI_FRM=new Myincassi(0,"AA");
INCASSI_FRM->show();
};
Myapp.h
#define MYAPP_H
#include <qwidget.h>
//CLASSE APPLICAZIONE
class Myapp:public QWidget{
Q_OBJECT
public:
Myapp(QWidget *parent=0,const char *name=0);
public slots:
void openincassi();
};
myincassi.cpp e myincassi.h non ti sertono sono una classe per l'incasso.
Myir.h
#define MYIR_H 0
# include <qobject.h>
# include <stdio.h>
#ifndef SHARP_H
#include </mnt/card/sharp/sharp.h>
#endif
class Myir:public QObject{
Q_OBJECT
public:
Myir(QObject *parent=0,const char *name=0);
void com_SendPasswContab();
void com_SendPasswSettings();
void com_SendWorkGroup();
void com_QueryStatus();
static void signal_handler_IO_simple_data (int signum);
void com_AzzeraContab();
private:
unsigned char irvet_out[20];
void datidallaseriale(int messaggio,int valore);
void svuotaporta();
void com_AddCheckSum(unsigned char *vet,int nbyte);
};
Myir.cpp
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#ifndef MYIR_H
#include </mnt/card/sharp/Myir.h>
#endif
Myir::Myir(QObject *parent, const char *name ):QObject( parent,name){
//un nuovo gestore ir e'stato aperto
}
void Myir::com_AddCheckSum(unsigned char *vet,int nbyte){
int f,ret;
if ((com_open!=-1)&&(nbyte>0)&&(nbyte<=20)){
printf("prima somma\n");
for (f=0;f<nbyte;f++)
vet[nbyte]=vet[nbyte]+vet[f];
printf("dopo somma\n");
for(f=0;f<comraddoppio;f++){
ret=write(fd_com,vet,nbyte);
}
//printf("AddChechSum\n");
}
else
printf("AddChechSum: com_open chiusa o val byte sballato\n");
}
void Myir::com_AzzeraContab(){
irvet_out[0]=0x9A;
irvet_out[1]=0x04;
irvet_out[2]=0x00;
irvet_out[3]=0x00;
irvet_out[4]=0x00;
irvet_out[5]=0x00;
Myir::com_AddCheckSum(&irvet_out[0],6);
}
void Myir::com_SendPasswContab(){
irvet_out[0]=0xB1;
irvet_out[1]=0x04;
irvet_out[2]=0xC8;
irvet_out[3]=0xA7;
irvet_out[4]=0x33;
irvet_out[5]=0x25;
Myir::com_AddCheckSum(irvet_out,6);
}
void Myir::com_SendPasswSettings(){
irvet_out[0]=0xB0;
irvet_out[1]=0x04;
irvet_out[2]=0xE4;
irvet_out[3]=0x3F;
irvet_out[4]=0x21;
irvet_out[5]=0x05;
Myir::com_AddCheckSum(irvet_out,6);
}
void Myir::com_SendWorkGroup(){
irvet_out[0]=0xA1;
irvet_out[1]=0x04;
irvet_out[2]=0x00;
irvet_out[3]=0x00;
irvet_out[4]=0x00;
irvet_out[5]=0x01;
Myir::com_AddCheckSum(irvet_out,6);
}
void Myir::com_QueryStatus(){
irvet_out[0]=0xA0;
irvet_out[1]=0x04;
irvet_out[2]=0x00;
irvet_out[3]=0x00;
irvet_out[4]=0x00;
irvet_out[5]=0x00;
Myir::com_AddCheckSum(irvet_out,6);
}
void Myir::svuotaporta(){
int bytes,ret;
unsigned char vet[1];
//leggendo dalla porta ho trovato meno bytes
printf("SvuotaPorta:err.lett-bzero buf ricez\n");
ioctl(fd_com,FIONREAD,&bytes);
while(bytes>0){
ret=read(fd_com,vet,1);
printf("byte letto %x %c\n",vet[0],vet[0]);
ioctl(fd_com,FIONREAD,&bytes);
}
}
static void Myir::signal_handler_IO_simple_data(int signum){
unsigned char vet[20],checksum;//,*stringa;
ret=ioctl(fd_com,FIONREAD,&bytes);
if (disable_com_event==0){
while (bytes>=1){
bzero(vet,sizeof(vet));
//leggi il carattere dell'intestazione
ret=read(fd_com,vet,1);
if (ret==1){
//e'un carattere conosciuto
switch(vet[0]){
case 0xA1:
case 0xA2:
case 0xA3:
case 0xA4:
case 0xA5:
case 0xA6:
case 0xA7:
case 0xA8:
case 0xA9:
case 0xAA:
case 0xAB:
case 0xAC:
case 0xAD:
case 0x90:
case 0x91:
case 0x92:
case 0x93:
case 0x94:
//carattere riconosciuto leggi la lunghezza del messaggio
ret=read(fd_com,&vet[1],1);
//evita valori superiori per evitare errori
if(vet[1]>50) ret=0;
if (ret==1){
//quanty bytes devo leggere
ret=read(fd_com,&vet[2],vet[1]);
if (ret==vet[1]){
//controlla il checksum
checksum=0;
for (f=0;f==(vet[1]+1);f++){//forse +2
checksum=checksum+vet[f];
}
if(vet[vet[1]+2]==checksum){
valx=(int *)&vet[2];
switch(vet[0]){
case 0xF1://nome apparecchio
// memcpy(gioco_cur.nome,&vet[2],vet[1]);
break;
case 0xAD://matricola apparecchio
//mi hanno mandato la matricola dell'apparecchio
// gioco_cur.matricola=*valx;
break;
case 0xA1://workgroup apparecchio
// gioco_cur.workgroup=*valx;
break;
case 0xA2://moltiplicatore IN
// gioco_cur.multidivin=0;
// gioco_cur.valrapin=*valx;
break;
case 0xA3://divisore IN
// gioco_cur.multidivin=1;
// gioco_cur.valrapin=*valx;
break;
case 0xA4://moltiplicatore OUT
// gioco_cur.multidivout=0;
// gioco_cur.valrapout=*valx;
break;
case 0xA5://divisore OUT
// gioco_cur.multidivout=1;
// gioco_cur.valrapout=*valx;
break;
case 0xA6://moltiplicatore hopper
// gioco_cur.multidivhopper=0;
// gioco_cur.valraphopper=*valx;
break;
case 0xA7://divisore hopper
// gioco_cur.multidivhopper=1;
// gioco_cur.valraphopper=*valx;
break;
case 0xA8://manomissioni
// gioco_cur.manomissioni=*valx;
break;
case 0xAA://hopp abil 1 dis 0
// gioco_cur.hopper_en=*valx;
break;
case 0xAB://dopp cont 1 abil
// gioco_cur.doppio_contr=*valx;
break;
case 0xAC://ultimo terminale che ha modificato la contabilita
// gioco_cur.ultimo_terminale=*valx;
break;
case 0x90://IN COUNTER
// gioco_cur.in_counter=*valx;
break ;
case 0x91://OUT COUNTER
// gioco_cur.out_counter=*valx;
break;
case 0x92://IN ERROR
// gioco_cur.in_error=*valx;
break;
case 0x93://PROGRESSIVE IN
// gioco_cur.prog_in=*valx;
break;
case 0x94://PROGRESSIVE OUT
// gioco_cur.prog_out=*valx;
break;
}
// funzioneesterna(0,(int)vet[0]);
}
else{
printf("checksum errato\n");
funzioneesterna(1,0);
svuotaporta();
}
}//if ret=vet(1)
else{
funzioneesterna(1,0);
svuotaporta();
}
}else{
svuotaporta();
}
break;
default:
//comando non riconosciuto
printf("byte letto %x %c\n",vet[0],vet[0]);
svuotaporta();
break;
}//fine switch
ioctl(fd_com,FIONREAD,&bytes);
//printf("are present:%d bytes\n",bytes);
}//leggendo il carattere dell'intestazione non ho trovato niente
else{
svuotaporta();
}
ioctl(fd_com,FIONREAD,&bytes);
}//while bytes>=1
}//dis com event
//printf("SIGIO signal ignored by com_event\n");
*/
}
int Myir::apriporta(void *callback,char *device){
struct termios oldtio,newtio;
struct sigaction saio;
int exstat=0;
// unsigned char vet[3];//,*vet_p;
// int f,bytes,ret,exstat;
// char genstr[100],genstr2[100];
if(callback==NULL){
printf("Error:callback non assegnata\nla seriale non sara' utilizzabile");
return -1;
}
if (device!=NULL){
printf("tentativo apertura porta=%s\n",device);
fd_com = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd_com <0) {
perror(device);
exstat=0;
}
else{
// funzioneesterna=callback;
com_open=1;
fcntl(fd_com,F_SETFL,FNDELAY);
//configurazione post apertura
saio.sa_handler = (void *) signal_handler_IO_simple_data;
// saio.sa_handler = &Myir::signal_handler_IO_simple_data;
//saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
//allow the process to receive SIGIO
fcntl(fd_com, F_SETOWN, getpid());
// Make the file descriptor asynchronous (the manual page says only
// O_APPEND and O_NONBLOCK, will work with F_SETFL...)
fcntl(fd_com, F_SETFL, FASYNC);
tcgetattr(fd_com,&oldtio); // save current port settings
// set new port settings for canonical input processing
bzero(&newtio, sizeof(newtio)); // clear struct for new port settings
//newtio.c_cflag = B9600 | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newtio.c_iflag = 0;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd_com, TCIFLUSH);
tcsetattr(fd_com,TCSANOW,&newtio);
exstat=1;
}
}
if (exstat==1){//siamo usciti bene la com e' aperta
com_open=1;
}
else{
com_open=-1;
}
return com_open;
}
void Myir::datidallaseriale(int messaggio,int valore){
printf("val= %d %c mess%d\n",valore,(unsigned char)valore,messaggio);
}
il codice non e' funzionante e sinceramente e' anche incasinato.
non so cosa ci puoi capire comunque te lo posto
sharp.h
#define SHARP_H 0
struct gioco_s{
//sezione lettura con password workgroup
char nome[20];//min 5 max 16
unsigned int workgroup; //A1-
unsigned int matricola;//AD-
unsigned int multidivin;//A2=molti A3=divi--1 molti 0 divi
unsigned int valrapin;//
unsigned int multidivout;//A4=molti A5=divi--1 molti 0 divi
unsigned int valrapout;
unsigned int multidivhopper;//A6=molti A7=divi--1 molti 0 divi
unsigned int valraphopper;
unsigned int manomissioni;//A8
unsigned int hopper_en;//AA valore....0 hopper disabilitato 1 hopper abilitato
unsigned int doppio_contr;//AB valore...0 doppio controllo entrate abilitato 1 disab
unsigned int ultimo_terminale;//AC valore....
//sezione con password contabilita'
unsigned int in_counter;//90 scatti*multi/din in
unsigned int out_counter;//91 scatti*multi/din in
unsigned int in_error;//92 scatti saltati*multi/div/in
unsigned int prog_in;//93
unsigned int prog_out;//94
};
int fd_com;//porta infrarossi
int comraddoppio=1;//quante volte bisogna scri
int disable_com_event=0;
int com_open;//indica se la seriale e'aperta
sharp.cpp
int main(int argc,char **argv){
//QApplication::setFont(QFont("Times",24,QFont::Bold));
QApplication a(argc,argv);//| QWidget::WStyle_NoBorderEx
Myapp mainw;
a.setMainWidget(&mainw);
mainw.show();
return a.exec();
}
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.