tutorials.de Buch-Aktion 05/2012
Like Tree2Danke
  • 1 Beitrag von Endurion
  • 1 Beitrag von titanic
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
5751
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    chefsalat- chefsalat- ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    40
    Hallo zusammen,
    folgendes Szenario:
    In einem Dialogfenster sollen beim Initialisieren verschiedene Variablen an einer SPS zum ereignisgesteuerten Lesen angemeldet werden.
    Das ganze läuft über Callback-Funktionen. (auf der Konsole gehts ohne Probleme)
    Jedes mal, wenn die Variable sich an der SPS geändert hat, soll sie im Dialogfenster aktualisiert werden.

    Das Anmelden der Variable an der SPS geht folgendermaßen:
    Code cpp:
    1
    2
    
    // Übertragen der SPS-Variablen beginnen 
    nErr = AdsSyncAddDeviceNotificationReq(pAddr, ADSIGRP_SYM_VALBYHND, ulHdlVar, &adsNotificationAttrib, Callback, hUser, &hNotification);
    Callback ist die Funktion, die aufgerufen werden soll, wenn sich eine Variable verändert hat. Ich werde für jede Variable eine eigene Funktion machen müssen. Aber hier der Übersichtlichkeit halber nur mal für eine Variable.


    ---------------------------------------------------------------------------------------------------------------

    Jetzt mein Problem:
    Wenn ich die Callback-Funktionen zu Member-Funktionen des Dialogfensters mache, bekomme ich folgenden Fehler:
    Code cpp:
    1
    2
    
    error C2664: 'AdsSyncAddDeviceNotificationReq' : Konvertierung des Parameters 5 von 'void (AmsAddr *,AdsNotificationHeader *,unsigned long)' in 'void (__cdecl *)(AmsAddr *,AdsNotificationHeader *,unsigned long)' nicht moeglich
    Keine Funktion mit diesem Namen im Gueltigkeitsbereich stimmt mit dem Zieltyp ueberein
    So bekomme ich aber dann Zugriff auf die Edit-Felder, in denen die Variablen aktualisiert werden sollen.

    Die entsprechende Header-Datei des Dialogfensters:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    
    class CTestDlg : public CDialog
    {
    // Konstruktion
    public:
        CTestDlg(CWnd* pParent = NULL); // Standard-Konstruktor
        void Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser);
        ...
    }

    Und die cpp-Datei des Dialogfensters:
    Code cpp:
    1
    2
    3
    4
    
    // Callback-Funktion
    void CTestDlg::Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser) {
        m_edit_lichtschranke.SetWindowText("test");
    }


    ---------------------------------------------------------------------------------------------------------------


    Mache ich die Callback-Funktionen nicht zu Member-Funktionen des Dialogfensters, habe ich keinen Zugriff auf die Edit-Felder und bekomme diese Fehlermeldung:
    Code cpp:
    1
    2
    
    error C2065: 'm_edit_lichtschranke' : nichtdeklarierter Bezeichner
    error C2228: Der linke Teil von '.SetWindowTextA' muss eine Klasse/Struktur/Union sein

    Die Header-Datei des Dialogfensters:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    void Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser);
     
    class CTestDlg : public CDialog
    {
    // Konstruktion
    public:
        CTestDlg(CWnd* pParent = NULL); // Standard-Konstruktor
        ...
    }

    Die cpp-Datei - also das Dialogfenster:
    Code cpp:
    1
    2
    3
    4
    
    // Callback-Funktion
    void Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser) {
        m_edit_lichtschranke.SetWindowText("test");
    }




    Der Übersichtlichkeit halber habe ich nur "test" in das Edit-Feld geschrieben.

    Zum Schluss noch mein System:
    - MS Visual C++ 6.0
    - Win XP
    - Multithreaded

    Kann mir bitte jemand helfen, wie ich zu einem Ergebnis komme, bzw. wo ich einen Fehler gemacht habe?

    Danke schon mal im Vorraus.
    Gruß chefsalat-
     

  2. #2
    Avatar von Endurion
    Endurion Endurion ist offline Mitglied Diamant
    Registriert seit
    Apr 2004
    Beiträge
    2.151
    Ja, der Nachteil, dass man die Klassen in C++ reingepfuscht hat. Member-Funktionen haben einen impliziten Parameter (this), der einen Pointer auf die aktuelle Instanz hält.

    Es gibt da verschiedene Möglichkeiten, eine der einfachen:


    A) die Callback-Member-Funktionen statisch machen
    B) eine statische Member-Variable vom Typ CTestDlg* (m_pDialog) als Member von CTestDlg
    C) im Constructor von CTestDlg setzt du m_pDialog auf this
    D) in den statischen Funktionen kannst du jetzt per m_pDialog-> auf die Edits zugreifen
    chefsalat- bedankt sich. 

  3. #3
    chefsalat- chefsalat- ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    40
    Danke für deine Anleitung, Endurion.
    Habs mal eben ausprobiert, bin aber noch nicht arg weiter gekommen.
    So siehts bis jetzt aus:

    testDlg.h
    Code cpp:
    1
    2
    3
    
    protected:
        static void Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser);
        static CTestDlg* m_pDialog;

    testDlg.cpp
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CTestDlg::IDD, pParent)
    {
        //{{AFX_DATA_INIT(CTestDlg)
        //}}AFX_DATA_INIT
        // Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        m_pDialog = this;
    }
     
    ...
     
    // Callback-Funktion
    void CTestDlg::Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser) {
        m_pDialog->m_edit_lichtschranke.SetWindowText("test");
    }

    Soweit hab ich deine Anweisungen befolgt und hoffentlich alles richtig gemacht, oder

    Jetzt bekomm ich aber 2 Fehlermeldungen mit denen ich nichts anfangen kann:
    Code cpp:
    1
    2
    
    testDlg.obj : error LNK2001: Nichtaufgeloestes externes Symbol "protected: static class CTestDlg * CTestDlg::m_pDialog" (?m_pDialog@CTestDlg@@1PAV1@A)
    Debug/test.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise

    Wer sieht, wo mein Fehler liegt

    Gruß chefsalat-
     

  4. #4
    titanic titanic ist offline Mitglied Silber
    Registriert seit
    May 2006
    Beiträge
    60
    Hallo chefsalat,

    Könnte es sein, dass deine statische Variable
    in der .cpp Datei gar nicht definiert ist?


    in der .cpp:

    CTestDlg* CTestDlg::m_pDialog = NULL;

    //wichtig!
    //static Variablen müssen extra definiert werden



    Gruß
    titanic
    chefsalat- bedankt sich. 

  5. #5
    chefsalat- chefsalat- ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    40
    Morgen titanic,

    in der .cpp:

    CTestDlg* CTestDlg::m_pDialog = NULL;
    ähm Wo soll das in die cpp rein?
    In den Konstruktor von CTestDlg? Ne, denke ich nicht. Da bringt mir eine Deklaration ja nix.



    Also in der .h hab ich jetzt mal:
    Code cpp:
    1
    2
    3
    
    protected:
        static void Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser);
        static CTestDlg* m_pDialog;

    Und in der .cpp siehts so aus:
    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CTestDlg::IDD, pParent)
    {
        //{{AFX_DATA_INIT(CTestDlg)
        //}}AFX_DATA_INIT
        // Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        CTestDlg::m_pDialog = this; 
        
    }
    ...
    // Callback-Funktion
    void CTestDlg::Callback(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser) {
        m_pDialog->m_edit_lichtschranke.SetWindowText("test");
    }

    Trotzdem kommt noch die Fehlermeldung:
    Code cpp:
    1
    2
    
    testDlg.obj : error LNK2001: Nichtaufgeloestes externes Symbol "protected: static class CTestDlg * CTestDlg::m_pDialog" (?m_pDialog@CTestDlg@@1PAV1@A)
    Debug/test.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise
     

  6. #6
    chefsalat- chefsalat- ist offline Mitglied Bronze
    Registriert seit
    Mar 2007
    Beiträge
    40
    Ahhhh, jetzt hab ichs...... *FREU*

    Code cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    CTestDlg* CTestDlg::m_pDialog = NULL;
     
     
    CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CTestDlg::IDD, pParent)
    {
        //{{AFX_DATA_INIT(CTestDlg)
        //}}AFX_DATA_INIT
        // Beachten Sie, dass LoadIcon unter Win32 keinen nachfolgenden DestroyIcon-Aufruf benötigt
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
        CTestDlg::m_pDialog = this; 
        
    }

    So tut's.

    DANKE!!
     

Ähnliche Themen

  1. Antworten: 3
    Letzter Beitrag: 11.02.09, 12:31
  2. Callback-Funktion aus For-Schleife abwarten
    Von PaRoX im Forum Borland CBuilder und VCL
    Antworten: 2
    Letzter Beitrag: 11.12.08, 10:35
  3. DLL: Globale Variable in CallBack Funktion verwenden
    Von KaiAusDerKiste2000 im Forum C/C++
    Antworten: 4
    Letzter Beitrag: 13.01.06, 11:12
  4. Trackback-Funktion programmieren
    Von adrianbechtold im Forum PHP
    Antworten: 1
    Letzter Beitrag: 09.07.05, 20:49
  5. Callback Funktion?
    Von Funjoy im Forum PHP
    Antworten: 0
    Letzter Beitrag: 30.12.04, 17:14