3

我试图让信号处理程序在 C++ 中工作,但不知道如何使用某些类属性。

信号处理程序在收到 SIGIO 信号时触发,我需要检查它是否用于正确的套接字。

我需要做的就是能够访问 privatesocket_和 public received()

namespace sigh {

 template<typename SomeType>
 class WorkWithSignals
 {
 public:
   void received( unsigned char* data, size_t len, unsigned int from );

 private:
   static void sigio_handler ( int sig, siginfo_t* siginfo, void* empty );
   int socket_;
 };

 extern "C" {
   void sigio_handler ( int sig, siginfo_t* siginfo, void* empty ) {
      if (siginfo->si_fd == ***socket_*** )
        ***received*** ();
   }
 }

}

除其他外,我尝试在定义之前定义一个静态结构变量,将其sigio_handler填充到定义之后的类构造函数中sigio_handler,但sigio_handler抱怨它不在范围内。

任何指针?

4

2 回答 2

1

您不能从静态方法访问成员变量(只是没有对象)。您也可以使您socket_的静态变量,并通过WorkWithSignals<...>::socket_.

于 2012-06-04T09:02:07.803 回答
1

信号处理程序是一个静态方法,因此它不会绑定到您的类的任何实例。

sigaction 手册页包含以下段落(与 siginfo_t 参数有关):

   * SIGPOLL/SIGIO fills in si_band and si_fd.  The si_band event is a bit
     mask containing the same values as are filled in the revents field by
     poll(2).  The si_fd field indicates the file descriptor for which the
     I/O event occurred.

假设您想继续当前基于信号的设计(poll() 可能更容易),我建议将文件描述符静态映射到 WorkWithSignals 类的实例。

然后在静态信号处理程序中,查找与给定文件描述符(您的 socket_ 字段)相关的实例,然后调用非静态方法对特定对象进行所需的工作。

在 WorkWithSignals 的声明中添加

static std::map<int, WorkWithSignals*> object_registry_;

以及源文件中所需的def。通过在注册信号处理程序之前添加到地图并在销毁对象之前从地图中删除来管理地图中的成员资格。然后:

   void sigio_handler ( int sig, siginfo_t* siginfo, void* empty ) {
      std::map<int, WorkWithSignals*>::iterator it = object_registry_.find(siginfo->si_fd);
      if(it == object_registry_.end())
          // handle error case
          assert(false);

      // Check that si_band is masked with the read flag as in the poll() call (look for revents)
      WorkWithSignals* obj = it->second;
      obj->received();
   }
于 2012-06-04T14:16:02.963 回答