2017-02-01 2 views
1

Я создаю C++-последовательный класс в Linux. Я пытаюсь зарегистрировать событие, когда поступают входящие данные.Как зарегистрировать событие с помощью termios.h в классе

Я работаю над доской Olimex Lime2. gcc version 4.6.3 (Debian 4.6.3-14)

Это ошибка, которую я получаю при попытке скомпилировать. conSerial.cpp: В 'ничтожной signal_handler_IO (INT)' Функция: conSerial.cpp: 15: 6: ошибка: 'EventHandler' не был объявлен в этой области

Я думаю, что это означает, что он не имеет доступа к классу. Возможно, я поступил неправильно. Любой совет будет принят во внимание.

Спасибо,

Стив

Заголовочный файл

#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 

Класс File

#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); 
    } 
} 

ответ

0

В вашем "Класс File", вы объявили функцию:

void signal_handler_IO (int status) 

, который относится к некоторому объекту под названием «EventHandler».

Этот объект не указан нигде, поэтому ошибка компиляции. Это так просто.

Это правда, что вы объявили класс с именем «conSerial», в котором есть член класса, называемый «EventHandler».

Однако, это класс прямо там. И член класса. Тот факт, что у вас есть какой-то класс, который происходит с объявлением члена класса с тем же именем, не имеет абсолютно никакого значения. C++ не работает таким образом. signal_handler_IO - это не метод в том же классе. Это даже не статическая функция класса в этом классе. Для доступа к члену класса вам нужна одна из двух вещей: либо экземпляр класса, либо где-то, чтобы получить доступ к его члену; или получить доступ к нему из нестатического метода в том же классе, который автоматически получает доступ к соответствующему члену любого экземпляра класса, чей метод он есть. Вот как работает C++.

И это основное объяснение вашей ошибки компиляции.

Это правда, что в другом методе класса, называемом open_port, вы берете указатель на эту функцию signal_handler_IO и устанавливаете его как обработчик сигнала для SIGIO. Опять же, это ничего не меняет.

Похоже, что вы намерены использовать свой conSerial класс. В этом случае чистое решение для головоломки является:

  1. Refactor класс, так что это строительства и уничтожение uses the singleton design pattern, как можно больше.

  2. Установите обработчик сигнала в конструкторе класса и удалите обработчик сигнала в его деструкторе.

  3. Попросите конструктора сохранить указатель на this в частном статическом члене класса, прежде чем устанавливать обработчик сигнала.

  4. Переместите основную часть signal_handler_IO в статический метод класса и не используйте signal_handler_IO ничего, кроме вызова метода статического класса.

  5. У вас есть метод статического класса, который использует указатель, который был настроен на шаге 3, для доступа к фактическому экземпляру вашего одноэлементного класса. Теперь он может делать то, что хочет сделать со своим членом класса EventHandler.

Смежные вопросы