2015-04-27 40 views
0

我想使用Linux内核信号将事件从模块事件发生异步传递给用户空间应用程序。我有以下方式在C工作:Boost ::将一个sigaction函数引用绑定到一个实例

void rcv_signal(int n, siginfo_t *info, void *unused) 
{ 
    // Do something interesting with the signal 
} 

// Register for updates from the kernel 
int main(int argc, char *argv[]) 
{ 
    struct sigaction sig; 
    sig.sa_sigaction = rcv_signal; // Function pointer 
    sig.sa_flags = SA_SIGINFO; 
    sigaction(SOME_CUSTOM_SIGNAL, &sig, NULL); 

    // Code to wait() then return 
} 

现在,我想移到C++实现。更具体地说,我想使用boost :: function/boost :: bind将sa_sigaction绑定到方法InputCapture::receive。但是,我正在努力获得正确的功能签名。

这里是InputCapture类的定义:

class InputCapture 
{ 
    public: InputCapture(uint8_t intimer) : timer(_timer) {} 
    public: ~InputCapture() {} 
    private: void receive(int n, siginfo_t *info, void *unused) {} 
    private: uint8_t timer; 
}; 

这里是修改sa_sigaction:

// Register for updates from the kernel 
struct sigaction sig; 
sig.sa_sigaction = boost::function<void (int n, siginfo_t *info, void *unused)> (
    boost::bind(&InputCapture::receive, this, _1)); 
sig.sa_flags = SA_SIGINFO; 
sigaction(SOME_CUSTOM_SIGNAL, &sig, NULL); 

不过,我得到以下编译错误:

In file included from /home/asymingt/export/rootfs/usr/include/boost/bind.hpp:22:0, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/LogicalStamp.hpp:12, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.hpp:4, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:1: /home/asymingt/export/rootfs/usr/include/boost/bind/bind.hpp: In instantiation of ‘struct boost::_bi::result_traits’: /home/asymingt/export/rootfs/usr/include/boost/bind/bind_template.hpp:15:48: required from ‘class boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >’ /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:41:57: required from here /home/asymingt/export/rootfs/usr/include/boost/bind/bind.hpp:69:37: error: ‘void (timesync::InputCapture::)(int, siginfo, void*)’ is not a class, struct, or union type typedef typename F::result_type type; ^ /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp: In constructor ‘timesync::InputCapture::InputCapture(uint8_t)’: /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:40:19: error: cannot convert ‘boost::function’ to ‘void ()(int, siginfo_t, void*) {aka void ()(int, siginfo, void*)}’ in assignment sig.sa_sigaction = boost::function ( ^ In file included from /home/asymingt/export/rootfs/usr/include/boost/function/detail/maybe_include.hpp:28:0, from /home/asymingt/export/rootfs/usr/include/boost/function/detail/function_iterate.hpp:14, from /home/asymingt/export/rootfs/usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:62, from /home/asymingt/export/rootfs/usr/include/boost/function.hpp:64, from /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:3: /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::void_function_obj_invoker3::invoke(boost::detail::function::function_buffer&, T0, T1, T2) [with FunctionObj = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*]’: /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:907:38: required from ‘void boost::function3::assign_to(Functor) [with Functor = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*]’ /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:722:7: required from ‘boost::function3::function3(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*; typename boost::enable_if_c::value>::value, int>::type = int]’ /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:1042:16: required from ‘boost::function::function(Functor, typename boost::enable_if_c::value>::value, int>::type) [with Functor = boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >; R = void; T0 = int; T1 = siginfo*; T2 = void*; typename boost::enable_if_c::value>::value, int>::type = int]’ /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:41:58: required from here /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:153:57: error: no match for call to ‘(boost::_bi::bind_t)(int, siginfo, void*), boost::_bi::list2, boost::arg<1> > >) (int&, siginfo*&, void*&)’ BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); ^ /home/asymingt/export/rootfs/usr/include/boost/function/function_template.hpp:75:36: note: in definition of macro ‘BOOST_FUNCTION_RETURN’ # define BOOST_FUNCTION_RETURN(X) X

我正在努力实现的可能性,如果有的话,我在哪里出错了?

+0

你是否缺少_1和_3之后的_2和_3?你的回调接受3个参数,所以我认为你需要绑定中的所有3个虚拟参数 – Vinbot

+0

好点 - 你是对的。但是,它似乎仍然不起作用。我收到一个错误:'/home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:在构造函数'timesync :: InputCapture :: InputCapture(uint8_t)'中: /home/asymingt/Workspace/Source/roseline/timesync/src/stamp/InputCapture.cpp:40:19:error:无法将'boost :: function '转换为void(*)(int,siginfo_t *(void *){aka void(*)(int,siginfo *,void *)}' sig.sa_sigaction = boost :: function ( – Andrew

+0

也许它与函数参数中的siginfo_t和siginfo *之间的差异有关 – Andrew

回答

1

你不能这样做。

请注意,sigaction::sa_sigaction是一个指向函数的指针。 boost::functionboost::bind的返回值都不能转换为函数指针!

+0

谢谢,Igor。你知道是否存在一个C++等效的sigation,我可以使用它,这将允许我绑定到一个成员函数? – Andrew

+0

@Andrew'sigaction'是一个简单的C函数,对于C++来说,你可以看看Boost.Asio库,它提供了s ['signal_set' object](http://www.boost.org/doc/libs/1_58_0/doc/html/boost_asio/reference/signal_set.html)。 –

+0

太好了 - 谢谢! – Andrew

相关问题