Event Handling



  • Hallo,

    ich habe mal allgemeine Fragen zum Eventhandling.

    Ich habe ein C++ Buch, finde aber im Stichwortverzeichneis nichts mit events oder Handler oder ähnliches... Deswegen auch Suchbegriffe, dass ich da was finde wäre schon super. (Ich habe "Einführung in die Programmierung mit C++" von Bjarne Stroustrup)

    Prinzipiell funktioniert das ganze Event Handling ja folgendermaßen?!:
    1. Ich warte darauf, dass ein Ereignis eintritt (z.B. Klicken eines Buttons)
    2. Nun wird das erkannt, es werden alle Prozesse unterbrochen und das Programm führt nun zunächst den Event Handler aus.
    3. Danach kehrt das Programm wieder zu dem vorher unterbrochenen Prozess zurück und es wurden (hfftl.) keine für diesen Prozess wichtigen Variablen, etc. verändert (Thema: Threadsicherheit oder?). Wird der Event Handler in einem anderen Thread bearbeitet?

    Ich suche auch eine Liste aller Ereignisse die implementierbar sind. Hat da jemand einen Link?

    Letztendlich möchte ich erfassen, wann eine Instanz einer selbst geschriebenen Klasse erzeugt worden ist. Dafür müsste ich doch ein eigenes Ereignis erstellen? Aber wie setze ich das um?


  • Mod

    C++ an sich bietet noch kein Framework dafür an. Deshalb steht's auch nicht im Stroustrup. Das müsstest du alles selber programmieren. Aber das willst du nicht. Also fertiges Framework - Ereignisbehandlung ist ein typisches GUI-Thema, daher bieten praktisch alle GUI-Frameworks so etwas an. Und damit wären wir dann hier:

    http://www.c-plusplus.net/forum/c1

    Und du musst nun eine Entscheidung treffen (oder dich erst beraten lassen): Welches Framework darf's sein?



  • Also zumindest mal unter Windows wird nix "unterbrochen" und vor allem nicht dein Thread. Vielmehr ist es so, dass dein Thread auf ein Event wartet und weiterläuft, wenn dann mal eines auftritt. Oder aber dein Thread macht die ganze Zeit was, aber nimmt sich ab und zu mal die Zeit zu schauen, was um ihn herum so geschieht. Oder er macht die ganze Zeit was und reagiert nicht auf Events und dann sagt Windows irgendwann, dass dein Programm nicht mehr reagiert.
    Aber das hat an sich nichts mit den Events in der C++-Welt zu tun, welche eher die Verknüpfung von Quelle mit n Zielen (Handlern) repräsentieren.



  • boost::signals(2) bietet das für reines C++ an.



  • Vielen Dank.

    Trotzdem habe ich nochmal eine Frage zu einem Programmablauf mit Event Handlern:

    1.In meinem Main Fenster habe ich ein Click Event auf einem Button, den ich in der Laufzeit auslöse.
    2.Innerhalb des Click Handler wird eine Klasse erzeugt, über die dann wiederum Methoden aufgerufen werden.
    3.Innerhalb einer dieser Methoden wird dann ein Event Handler hinzugefügt (der angibt, wann eine Klasse erstellt worden ist = "Loaded" event).

    Nun habe ich das ganze mit dem Debugger verfolgt. Anscheinend wird der Click Event Handler abgeschlossen und erst danach springt das Programm in den neuen Event Handler des "Loaded" events. Komischerweise- oder eben nicht?!- macht dieser Event Handler nicht das was er machen sollte. Scheinbar enthalten benutzte Variablen, die vorher definitv beschrieben waren, nur noch Nullverweise... Kann es sein, dass die Klasse, die im Click Event erzeugt wird, mit dem Abschließen des Click Events schon "zerstört" wird und erst dann der Loaded Event Handler aufgerufen wird und damit versucht auf Nullverweise zu zu greifen?



  • Neulinger schrieb:

    Vielen Dank.

    Trotzdem habe ich nochmal eine Frage zu einem Programmablauf mit Event Handlern:

    1.In meinem Main Fenster habe ich ein Click Event auf einem Button, den ich in der Laufzeit auslöse.
    2.Innerhalb des Click Handler wird eine Klasse erzeugt, über die dann wiederum Methoden aufgerufen werden.
    3.Innerhalb einer dieser Methoden wird dann ein Event Handler hinzugefügt (der angibt, wann eine Klasse erstellt worden ist = "Loaded" event).

    Nun habe ich das ganze mit dem Debugger verfolgt. Anscheinend wird der Click Event Handler abgeschlossen und erst danach springt das Programm in den neuen Event Handler des "Loaded" events. Komischerweise- oder eben nicht?!- macht dieser Event Handler nicht das was er machen sollte. Scheinbar enthalten benutzte Variablen, die vorher definitv beschrieben waren, nur noch Nullverweise... Kann es sein, dass die Klasse, die im Click Event erzeugt wird, mit dem Abschließen des Click Events schon "zerstört" wird und erst dann der Loaded Event Handler aufgerufen wird und damit versucht auf Nullverweise zu zu greifen?

    Ohne Code ist das schwer zu sagen, aber es klingt so, als wenn Deine Events asynchron arbeiten (das ist der Normalfall). Sprich, Du löst ein Event aus, aber die auslösende Funktion kommt sofort zurück, obwohl das Event noch nicht abgearbeitet wurde. Wenn die Behandlung deines Events nun irgendwelche Daten von der auslösenden Instanz benötigt, welche z.B. als Zeiger übergeben wurden, dann kann es sein, dass die Daten zum Zeitpunkt der Eventbehandlung nicht mehr existieren.



  • Ich verwende für Events in diversen Anwendungen libsigc++. Ist auch reines C++ und kommt von gnome. Ist auch unter Windows somit einsetzbar.
    Allerdings verwende ich das nur, wenn ich entsprechend Callbacks brauche und keine GUI-Library einsetze, wie aktuell mein Game-Framework. Dort mache ich sehr starken gebrauch von libsigc++ wie Render-Event, Logic-Update-Event, Keyboard-, Mausevents usw.
    Bei den meisten GUI Libraries ist sowas mitgeliefert und sollte dann auch verwendet werden.



  • class B;
    class myClass
    {
    public:
        string text;
        B* b;
        myClass()
        {
            text = "Inhalt";
            b = new B();
            printf("\n%s\n\n", text.c_str()); //Ausgabe: "Inhalt"
        }
    
        void _Do(Base info)
        {
            IXRFrameworkElement inst = info.CreateInstance();   
    	    inst->AddLoadedEventHandler(CreateDelegate(this, &myClass::_InstanceLoaded)); // success
        }
    
        HRESULT myClass::_InstanceLoaded(IXRDependencyObject* pSender, XRRoutedEventArgs* pArgs)
        {
            printf("\ntext: %s\n\n", text.c_str()); //Ausgabe "text: (null)"
            printf("\nb: %s\n\n", b->GetStringValue().c_str()); //Absturz beim Aufruf der Methode von b   
        }
    };
    

    Click Event Handler der Main:

    HRESULT MainPage::MyButton_Click (IXRDependencyObject* pSender, XRMouseButtonEventArgs* pArgs)
    {
        Base info = Base();	 
    	myClass test = myClass();
    	test._Do();
    	HRESULT hr = E_NOTIMPL;
        return hr;
    }
    

    Das heißt, das zwar anfangs der "string text" einen inhalt hatte, aber zu dem Zeitpunkt, wo der Loaded Event Handler auftritt schon wieder gelöscht wurde. Genauso sieht es mit dem zeiger b aus... Wie kann ich aber umgehen, dass die Variablen schon gelöscht sind, bevor der Handler aufgerufen wurde?


Anmelden zum Antworten