如何在类中使用termios.h注册事件

时间:2017-02-01 02:38:35

标签: c++

我正在Linux中创建一个c ++序列类。我正在尝试在收到传入数据时注册一个事件。

我正在使用Olimex Lime2板。 gcc版本4.6.3(Debian 4.6.3-14)

这是我在尝试编译时遇到的错误。 conSerial.cpp:在函数'void 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

班级档案

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

1 个答案:

答案 0 :(得分:0)

在您的&#34;类文件&#34;中,您声明了一个函数:

void signal_handler_IO (int status)

指的是一个名为&#34; EventHandler&#34;。

的对象

在任何地方都没有声明这样的对象,因此编译错误。它就这么简单。

你确实声明了一个名为&#34; conSerial&#34;的类,它碰巧有一个名为&#34; EventHandler&#34;的类成员。

然而,这就是那里的一个班级。和一个班级成员。事实上,你有一些类恰好声明了一个同名的类成员,这无论如何都没有任何区别。 C ++没有这种方式工作。 signal_handler_IO不是同一类中的方法。它甚至不是该类中的静态类函数。要访问类成员,您需要以下两种方法之一:要么是某个类的实例,要么访问其成员;或者从同一个类中的非静态方法访问它,它自动访问其方法的任何类实例的相应成员。这就是C ++的工作原理。

这是编译错误的基本解释。

确实,在一个名为&#34; open_port&#34;的另一个类方法中,您获取一个指向此signal_handler_IO函数的指针,并将其安装为SIGIO的信号处理程序。同样,这并没有真正改变任何事情。

您似乎打算将conSerial班级作为单身人士。在这种情况下,最难解决的难题是:

  1. 尽可能地重构班级,使其构建和破坏uses the singleton design pattern

  2. 在类的构造函数中安装信号处理程序,并在其析构函数中卸载信号处理程序。

  3. 在安装信号处理程序之前,让构造函数在私有静态类成员中保存指向this的指针。

  4. 将大部分signal_handler_IO移动到静态类方法中,除了调用静态类方法外,signal_handler_IO不执行任何操作。

  5. 您是否使用静态类方法使用在步骤3中设置的指针访问您的单例类的实际实例。现在,它可以做任何想做的事情&#34; EventHandler&#34;班级成员。