2017-02-01 7 views
1

Ich mache eine C++ serielle Klasse in Linux. Ich versuche, ein Ereignis zu registrieren, wenn eingehende Daten empfangen werden.Wie registriert man ein Ereignis mit termios.h in einer Klasse

Ich arbeite an einem Olimex Lime2 Board. gcc Version 4.6.3 (Debian 4.6.3-14)

Dies ist der Fehler, den ich beim Kompilieren bekomme. conSerial.cpp: 'Leer signal_handler_IO (int)' In Funktion: conSerial.cpp: 15: 6: Fehler: 'Eventhandler' wurde in diesem Rahmen nicht erklärt

Ich denke, das bedeutet, dass sie keinen Zugang hat zur Klasse. Vielleicht bin ich das in die falsche Richtung gegangen. Jeder Rat würde geschätzt werden.

Danke,

Steve

Header-Datei

#ifndef CONSERIAL_H_ 
#define CONSERIAL_H_ 

#include "termios.h" 
#include <sys/signal.h> 
class conSerialEvents 
{ 
    public: 
     virtual void onReceive(); 
}; 
class conSerial 
{ 
    public: 
     conSerial(const char *port_, termios *options_, conSerialEvents *EventHandler_); 
     conSerial(const char *port_, termios *options_); 
     int open_port(void); 
     int send(const char *s, size_t len); 
     void close_port(void); 
    private: 

     conSerialEvents *EventHandler; 
     static const int PORT_OPEN = 0; 
     termios *options; 
     const char *port; 
     int fd; 
     struct sigaction saio; 
}; 

#endif 

Klasse Datei

#include <stdio.h>  //Standard input/output definitions 
#include <string.h>  //String function definitions 
#include <unistd.h>  //UNIX standard function definitions 
#include <fcntl.h>  //File control definitions 
#include <errno.h>  //Error number definitions 
#include <termios.h> //POSIX terminal control definitions 
#include <iostream>  //Input-Output Streams 
#include "conSerial.h" //Header for this file 
using namespace std; 
void signal_handler_IO (int status); 
void signal_handler_IO (int status) 
{ 
    std::cout << "Signal" << std::endl; 
    //This section fails because it can't see the class I think. 
    if (EventHandler) 
    { 
     EventHandler->onReceive(); 
    } 
    //End this section 

} 

conSerial::conSerial(const char *port_, termios *options_) 
{ 
    this->EventHandler = 0L; 
    const char *port; 
    termios *options; 
    fd = -1; 

} 

conSerial::conSerial(const char *port_, termios *options_, conSerialEvents *EventHandler_) 
{ 
    this->EventHandler = EventHandler_; 
    const char *port; 
    termios *options; 
    fd = -1; 
} 

int conSerial::open_port(void){ 

    struct termios options; 

    fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY); 

    if (fd == -1){ 
     //Could not open the port. 
     std::cout << "Port Failed to Open"; 
    }else{ 
     saio.sa_handler = signal_handler_IO; 
     sigemptyset(&saio.sa_mask); 
     saio.sa_flags = 0; 
     saio.sa_flags = SA_NODEFER; 
     saio.sa_restorer = NULL; 
     sigaction(SIGIO,&saio,NULL); 

     fcntl(fd, F_SETOWN, getpid());  
     fcntl(fd, F_SETFL, FNDELAY); // Sets the read() function to return NOW and not wait for data to enter buffer if there isn't anything there. 

     //Configure port for 8N1 transmission 
     tcgetattr(fd, &options);     //Gets the current options for the port 
     cfsetispeed(&options, B38400);    //Sets the Input Baud Rate 
     cfsetospeed(&options, B38400);    //Sets the Output Baud Rate 
     options.c_cflag |= (CLOCAL | CREAD);  //? all these set options for 8N1 serial operations 
     options.c_cflag |= PARENB;     //? 
     options.c_cflag &= ~CSTOPB;     //? 
     options.c_cflag &= ~CSIZE;     //? 
     options.c_cflag |= CS7;      //? 

     tcsetattr(fd, TCSANOW, &options);   //Set the new options for the port "NOW" 

     std::cout << "seems like everything is ok, keep going\n"; 
    }; 

    return (fd); 
}; 

int conSerial::send(const char *s, size_t len){ 
    int written; 
    written = 0; 
    if (fd==-1){ // 
     // If this is -1 it means that the port is not open. 
     std::cout << "The port is not open." << std::endl; 
    }else{ 
     // The port is open 
     tcdrain(fd); 
     written = write(fd, s, len); 
    } 
    return written; 
} 

void conSerial::close_port(void){ 
    if (fd !=-1){ 
     close(fd); 
    } 
} 

Antwort

0

In Ihrem "Class File", eine Funktion erklärt:

void signal_handler_IO (int status) 

bezieht sich auf ein Objekt namens "EventHandler".

Kein solches Objekt ist irgendwo deklariert, daher der Kompilierungsfehler. So einfach ist das.

Es ist wahr, dass Sie eine Klasse namens "conSerial" deklariert haben, die zufällig ein Klassenmitglied namens "EventHandler" hat.

Aber das ist eine Klasse genau dort. Und ein Klassenmitglied. Die Tatsache, dass Sie eine Klasse haben, die zufällig ein Klassenmitglied mit demselben Namen deklariert, macht überhaupt keinen Unterschied. C++ funktioniert nicht so. signal_handler_IO ist keine Methode in derselben Klasse. Es ist nicht einmal eine statische Klassenfunktion in dieser Klasse. Um auf ein Klassenmitglied zuzugreifen, benötigen Sie eines von zwei Dingen: entweder eine Instanz einer Klasse, irgendwo, um auf ihr Mitglied zuzugreifen; oder greifen Sie auf eine nicht statische Methode derselben Klasse zu, die automatisch auf das entsprechende Mitglied der Klasseninstanz zugreift, deren Methode es ist. So funktioniert C++.

Und das ist die grundlegende Erklärung für Ihren Kompilierungsfehler.

Es stimmt, dass Sie in einer anderen Klassenmethode namens "open_port" einen Zeiger auf diese signal_handler_IO-Funktion nehmen und als Signalhandler für SIGIO installieren. Auch das ändert nichts wirklich.

Es scheint, dass Sie Ihre conSerial Klasse ein Singleton sein möchten. In diesem Fall ist die sauberste Lösung für Ihre conundrum:

  1. Umgestalten der Klasse so, dass es den Aufbau und Zerstörung uses the singleton design pattern, so viel wie möglich.

  2. Installieren Sie den Signalhandler im Konstruktor der Klasse und deinstallieren Sie den Signalhandler in seinem Destruktor.

  3. Lassen Sie den Konstruktor in einem privaten statischen Klassenmember einen Zeiger auf this speichern, bevor Sie den Signalhandler installieren.

  4. Verschieben Sie den Großteil von signal_handler_IO in eine statische Klassenmethode, und führen Sie signal_handler_IO nichts aus, außer die statische Klassenmethode aufzurufen.

  5. Haben Sie statische Klassenmethode verwenden Sie den Zeiger, der in Schritt 3 eingerichtet wurde, greifen Sie auf die tatsächliche Instanz Ihrer Singleton-Klasse. Jetzt kann es mit seinem Klassenmitglied "EventHandler" machen, was es will.

Verwandte Themen