Reputation: 91
I would like to use a Linux kernel signal to asynchronously communicate the occurrence of an event from a module to a user-space application. I have this working in C in the following way:
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
}
Now, I would like to move to C++ implementation. More specifically, I would like to use boost::function / boost::bind to bind the sa_sigaction to a method InputCapture::receive
. However, I am struggling to get the correct function signature.
Here is the definition of the InputCapture Class:
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;
};
And here is the modified 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);
However, I get the following compilation error:
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
Is what I am trying to achieve possible, and if so, where have I gone wrong?
Upvotes: 0
Views: 1008
Reputation: 15075
You cannot do this.
Note that sigaction::sa_sigaction
is a pointer to function. Neither boost::function
, nor the return value of boost::bind
are convertible to a function pointer!
Upvotes: 1