Callback Funktionen in C++



  • Hallo zusammen,

    ich hoffe jemand heir kann mir mit meinem Problem weiterhelfen. Ich habe einige Funktionen in C, die ich jetzt aber in C++ benötige. Einer Funktion wird dabei ein Callback Funktion als Argument übergeben:

    Alter Code:

    float EvaluateCurve(float f[],void *context)
    {
    .
    .
    .
    }

    void test() {
    .
    .
    amoeba(pfp, fy, 3, .0001f, EvaluateCurve, &n, (void*)&p);
    .
    .
    }

    Neuer Code:
    class Test
    {
    public:
    float EvaluateCurve(float f[],void *context)

    }
    float (Test::*lpFunc)(float f[], void *context,) = &Test::EvaluateCurve;

    void test()
    {
    .
    .
    Test test;
    amoeba(pfp, fy, 3, .0001f,(test.* lpFunc)(pfp[0], &p),&n,(void*)&p);
    .
    .
    }

    Folgende Fehlermeldung erscheint beim kompilieren:
    error C2664: 'Test::amoeba' : cannot convert parameter 5 from 'float' to 'float (__cdecl *)(float [],void *)'

    Weiss jemand eine Antowrt darauf, wie die Syntax auszusehen hat?

    Danke



  • ..hab noch was vergessen:

    Die Funktion amoeba ist in der Klasse Test wie folgt definiert:

    int amoeba(float **p, float y[], int ndim, float ftol,float (*funk)(float [],void *context), int *nfunk, void *context);



  • Dieser Thread wurde von Moderator/in estartu aus dem Forum MFC (Visual C++) in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Tisla schrieb:

    ..hab noch was vergessen:

    Die Funktion amoeba ist in der Klasse Test wie folgt definiert:

    int amoeba(float **p, float y[], int ndim, float ftol,float (*funk)(float [],void *context), int *nfunk, void *context);

    Du verlangst hier eine Funktion, keine Methode. Der Unterschied zwischen Funktion und Methode ist, dass eine Methode von einer Klasseninstanz abhängig ist.
    Befindet sich Deine Funktion im Namensraum einer Klasse, so muss sie statisch sein - also eben unabhängig von der Instanz.

    Möchtest Du einen Methodenzeiger übergeben, so lautet die Deklaration

    int amoeba(float **p, float y[], int ndim, float ftol,float (Test::*funk)(float [],void *context), int *nfunk, void *context);
    

    In dem Fall übergibst Du aber nur einen Zeiger auf eine Methode, aber nicht die Instanz, auf den Du die Methode anwenden kannst. Das musst Du
    zusätzlich übergeben oder Dir sonstwo besorgen. Eine Methode kannst Du schließlich nur in Abhängigkeit zu einer Instanz anwenden.

    Der Aufruf sieht dann so aus:

    void bla( float Test::*func( int value ) )
    {
      Test t;
      Test *pt = &t;
    
      t.*func( 1 );
      pt->*func( 2 );
    }
    


  • Also irgendwie habe ich jetzt den Überblick verloren. Die Funktionen sind jetzt folgendermassen definiert:

    test.h:

    class Test:public IntrusivePtrBase
    {
    public:
      float CurveEvaluation(float f[],void *context, int minRadius);
      int amoeba(float **p, float y[], int ndim, float ftol,float (ModelLUT::*funk)(float [],void *context, int minRadius), int *nfunk, void *context);
    };
    
    float (Test::*lpFunc)(float f[], void *context, int minRadius) = &Test::CurveEvaluation;
    
    typedef boost::intrusive_ptr< Test > SPTEST;
    

    test.c

    bool Test::Init()
    {
    ....
    SPTEST test;
    amoeba(pfp, fy, 3, .0001f,((*test).* lpFunc)(pfp[0], &p, minRadius),&n,(void*)&p);
    .....
    
    }
    

    Leider bekomme ich immer noch den Fehler:
    error C2664: 'Test::amoeba' : cannot convert parameter 5 from 'float' to 'float (__thiscall Test::* )(float [],void *,int)'



  • Tisla schrieb:

    bool Test::Init()
    {
      amoeba(pfp, fy, 3, .0001f,((*test).* lpFunc)(pfp[0], &p, minRadius),&n,(void*)&p);
    }
    

    lpFunc ist bereits vom richtigen Typ.
    Dein Aufruf muss lauten:

    bool Test::Init()
    {
      amoeba(pfp, fy, 3, .0001f, lpFunc, &n,(void*)&p );
    
      /* oder auch */
    
      amoeba(pfp, fy, 3, .0001f, &Test::EvaluateCurve, &n,(void*)&p );
    }
    

    Du übergibst einen Methoden-Zeiger, aber Du rufst die Methode nicht auf.

    Wenn Du das Ergebnis der Methode übergeben möchtest, musst Du schließlich nur ein float übergeben.
    Die Argumente für lpFunc musst Du Dir in amoeba() besorgen - oder gegebenenfalls zusätzlich der Funktion amoeba() übergeben.
    Der Methodenzeiger kann jedoch keine zusätzlichen Variablen mitnehmen.

    Vergleiche das mit Deinem C Quellcode:

    amoeba(pfp, fy, 3, .0001f, EvaluateCurve, &n, (void*)&p);
    

    Hier übergibst Du ebenfalls keine Arguemnte, sondern ausschließlich einen Funktionszeiger.


Log in to reply