2

I'm having problems with signal function, i need that the second parameter call a function of my class

signal (SIGINT, myClass_function);

but as far as i know, it needs to be static void. And so i can not access the same instance of my object to access the variables that i need

Foo.h

class Foo {
public:
  std::vector<my_struct> vm = std::vector<my_struct>(50);

  static void myClass_function(int parameter) {
    // handling signal here
    // i need to access vm here
  }

};

Foo.cpp

void Foo::something() {
  // call signal
  signal(SIGINT, myClass_function);    
}

if user press ctrl+c, all data of vector vm need to be clean. No way to do that? anyone can help me?

chema989
  • 3,962
  • 2
  • 20
  • 33
Melissia_M
  • 323
  • 2
  • 13
  • 1
    Help you with what? Your understanding of how a signal handler works is absolutely correct. The signal handler gets invoked asynchronously when the process receives a signal. That's it. Nothing more. Nothing less. Not only does the signal handler does not get any other parameter of some kind, it can't call any library function, or code, that's not reentrant. All the signal handler has, to work with, is that it's been invoked as a result of a signal. It's up to the signal handler to figure out what it needs, and where to get it. – Sam Varshavchik Jun 16 '16 at 03:05
  • And when there's a signal, which `Foo`'s `vm` should be used by the signal handler? – md5i Jun 16 '16 at 03:07
  • Check the answer of Luc Touraille in this post: [Is it possible to use signal inside a C++ class?](http://stackoverflow.com/questions/343219/is-it-possible-to-use-signal-inside-a-c-class). – chema989 Jun 16 '16 at 03:21
  • 1
    I tried this, the second possibility he suggested. but I'm having the following error when compiling : " undefined reference to class::instance " – Melissia_M Jun 16 '16 at 03:36
  • 1
    You need to *define* class::instance. The linked answer doesn't show how to do this. – n. m. could be an AI Jun 16 '16 at 05:03

1 Answers1

2

The solution can be declared a Singleton Wrapper that handle the right instance. I propose the next code based on the idea of Luc Touraille:

#include <iostream>
#include <signal.h>


class Foo;


class Wrap {
    Foo* foo;

    Wrap() = default;

public:
    static Wrap& getInstance() {
        static Wrap* w = new Wrap();
        return *w;
    }

    void set(Foo* foo_) {
        foo = foo_;  
    }

    Foo* get() {
        return foo;   
    }
};


class Foo {
    int x;

public:
    Foo(int x_)
        : x(x_) { }

    void something() {
        // call signal
        static Wrap& w = Wrap::getInstance();
        w.set(this);
        signal(SIGINT, Foo::myHandler);
        raise(SIGINT);
    }

    static void myHandler(int parameter) {
        static Wrap& w = Wrap::getInstance();
        fprintf(stderr, "%d  %d\n", w.get()->x, parameter);
    }
};

int main() {
    Foo f(10);
    Foo f2(100);
    f.something();
    f2.something();
}

Output:

10  2
100  2

I suggest you this, if you want have several instances of Foo. On the other hand, if you only need a instance of Foo, you do not need the Singleton Wrap and Foo should be Singleton.

chema989
  • 3,962
  • 2
  • 20
  • 33