I am doing something like this:
#include <signal.h> class myClass { public: void myFunction () { signal(SIGIO,myHandler); } void myHandler (int signum) { /** * Handling code */ } }
I am working on Ubuntu, using gcc.
But it won't compile. It is complaining with:
error: the argument with type
void (MyClass::)(int)
doesn't agree withvoid (*) (int)
Any clues? Or maybe it is just that I cannot use a signal inside classes? Are signals only allowed in C?
The error message is an approximate translation because my compiler is not in English.
A signal is a software generated interrupt that is sent to a process by the OS because of when user press ctrl-c or another process tell something to this process.
It is not safe to call all functions, such as printf , from within a signal handler. A useful technique is to use a signal handler to set a flag and then check that flag from the main program and print a message if required.
Absolutely. You can pass integers and pointers to signal handlers by using sigqueue() instead of the usual kill().
The second parameter of signal should be a pointer to a function accepting an int and returning void. What you're passing to signal is a pointer to a member function accepting an int and returning void (its type being void (myClass::*)(int)
). I can see three possibilities to overcome this issue:
1 - Your method myHandler
can be static: this is great, make it static
class myClass { public: void myFunction () { signal(SIGIO, myClass::myHandler); } static void myHandler (int signum) { // handling code } };
2 - Your method shouldn't be static: if you're planning to use signal with only one instance, you can create a private static object, and write a static method that simply call the method on this object. Something along the lines of
class myClass { public: void myFunction () { signal(SIGIO, myClass::static_myHandler); } void myHandler (int signum) { // handling code } static void static_myHandler(int signum) { instance.myHandler(signum); } private: static myClass instance; };
3 - However, if you're planning on using the signal with multiple instances, things will get more complicated. Perhaps a solution would be to store each instance you want to manipulate in a static vector, and invoking the method on each of these :
class myClass { public: void myFunction () // registers a handler { instances.push_back(this); } void myHandler (int signum) { // handling code } static void callHandlers (int signum) // calls the handlers { std::for_each(instances.begin(), instances.end(), std::bind2nd(std::mem_fun(&myClass::myHandler), signum)); } private: static std::vector<myClass *> instances; };
and somewhere, do a single call to
signal(SIGIO, myClass::callHandlers);
But I think that if you end up using the last solution, you should probably think about changing your handling design :-)!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With