Callbackfunktion zwischen Klassen



  • Hallo,
    ich habe eine Nicht-MFC-Klasse, die Daten an eine Callbackfunktion weiter
    gibt. Diese Callbackfunktion soll sich nun aber innerhalb einer MFC-Klasse
    befinden.
    Wenn ich es so versuche, bekomme ich einen Fehler:

    void CClass1::Begin(void(*CBFunc)(String))
    {
       [...]
       CBFunc("Hallo");
    }
    
    void CClass2::Begin(void)
    {
       NonMFCObject->Begin(&CMFCClass::Callback);
    }
    
    void CClass2::Callback(String strMessage)
    {
       [...]
    }
    

    und zwar sagt mir der Compiler dann:
    error C2664: cannot convert parameter 1 from 'void (__thiscall CClass2::* )(String)' to 'void (__cdecl *)(String)'

    Um das ganze Allgemein zu halten, kann ich in meiner CClass1 die Callbackfunktion aber nicht irgendwie so angeben:

    void CClass1::Begin(void(*CClass2::Callback)(String))
    

    sofern das überhaupt ginge...
    Weiß jemand Rat, oder muss ich meine Callbackfunktion jetzt definitiv als globale Funktion definieren und nicht innerhalb einer Klasse?

    Norman.



  • Hm.
    Mehrere Möglichkeiten...

    1: gib der Callback Funktion ein void* Parameter.

    class A
    {
    public:
        void Foo(void (*callback)(void*), void* param);
    };
    
    class B
    {
    public:
        void Bar();
    
        static void StaticBar(void* param)
        {
            static_cast<B*>(param)->Bar();
        }
    
        void Baz(A* a)
        {
            a->Foo(&B::StaticBar, this);
        }
    };
    

    2: verwende eine "Interface Klasse"

    class CallbackXYZ
    {
    public:
        virtual void Bar() = 0;
    };
    
    class A
    {
    public:
        void Foo(CallbackXYZ* callback);
    };
    
    class B : private CallbackXYZ
    {
    public:
        void Bar();
        void Baz(A* a)
        {
            a->Foo(this);
        }
    };
    

    3: verwende boost::function und boost::bind

    class A
    {
    public:
        void Foo(boost::function<void()> const& callback);
    };
    
    class B
    {
    public:
        void Bar();
        void Baz(A* a)
        {
            a->Foo(boost::bind(&B::Bar, this));
        }
    };
    

    4: Strick dir selbst irgendwas mit Template-Magic


Log in to reply