Zeiger auf Memberfunktion in Zeiger auf Funktion umwandeln



  • Ich habe eine Klasse für Signalbehandlung, die u.a. eine Funktion enthält, die konkret für die Behandlung der Signale zuständig ist (also aufgerufen wird wenn ein Signal auftritt). Im Konstruktor soll mittels der sigaction-Funktion (aus signal.h) diese Signalbehandlungsfunktion registriert werden. Die sigaction erwartet allerdings einen normalen Zeiger auf eine Funktion, meine Funktion ist aber eine Member-Funktion. Eine Umwandlung zwischen beiden ist wohl nicht möglich. Ich könnte zwar die Funktion static machen, dann würde es gehen, allerdings benötige ich zur Behandlung der Signale Zugriff auf die Membervariablen, also kommt diese Möglichkeit nicht in Frage.

    Weiß vielleicht jemand wie ich es sonst machen könnte? Also wie kann ich einen Zeiger auf eine Memberfunktion als einen normalen Funktionszeiger übergeben?

    So sieht meine Klasse in etwa aus:

    class Test {
      Test();
      void signalHandler(int, siginfo_t, void*);
    
    // ...
    }
    
    Test::Test() {
      struct sigaction sa;
      sa.sa_flags = SA_SIGINFO;
      sa.sa_sigaction = &signalHandler;  // funktioniert nicht
      sigaction(SIGSEGV, &sa, NULL);
      //...
    };
    


  • Kannst es evtl. mit einem Funktor versuchen ... aber wird schwer ... wenn du der Funktion in irgendeiner weise einen this-Zeiger übergeben kannst, reicht das auch ... dann kannst du in der static-Method dann einfach per this-Zeiger die normale Funktion aufurfen ...



  • Warum machst Du das Signal nicht in ein Interface? Dann kann jede Klasse die eins braucht davon ableiten und du übergibst nur einen Zeiger auf die Klasse?
    So würde ich es machen. Oder Boost::Signals nehmen 😛 *scherz*

    class IStandardSignal
    {
    public:
      virtual void signalHandler(int, siginfo_t, void*) = 0;
    };
    
    class Test : public IStandardSignal
    {
      Test();
      virtual void signalHandler(int, siginfo_t, void*);
    
    // ...
    };
    
    Test::Test() {
      struct sigaction sa;
      sa.sa_flags = SA_SIGINFO;
      sa.sa_sigaction = this;
      sigaction(SIGSEGV, &sa, NULL);
      //...
    };
    

    rya.



  • When passing a Callback to a system that expects to call a C function, but one wants it to execute the method function of a particular instance of an object written in C++, one uses a short trampoline to convert the C function-calling convention to the C++ method-calling convention. One method of writing such a trampoline is to use a thunk -- see "Thunking in Win32 with C++" by Einar Otto Stangvik.



  • Scorcher24 schrieb:

    Warum machst Du das Signal nicht in ein Interface? Dann kann jede Klasse die eins braucht davon ableiten und du übergibst nur einen Zeiger auf die Klasse?
    So würde ich es machen. Oder Boost::Signals nehmen 😛 *scherz*

    Ich will Signale behandeln, die vom System kommen, speziell Speicherzugriffsverletzungen. Dazu benutze ich die sigaction-Struktur aus der signal.h und die erwartet als übergabe einen Zeiger auf eine Funktion mit der Signatur void(int, siginfo_t*, void*). Also würde auch dein Beispiel nicht funktionieren. Das Problem ist, das man einen Zeiger auf eine Memberfunktion nicht in einen Zeiger auf eine normale C-Funktion umwandeln kann.

    @trampoline-freak: Das schau ich mir mal an, sieht ganz brauchbar aus.


Anmelden zum Antworten