2017-02-11 3 views
0

Ich möchte eine Funktion mit gsl integrieren. Dazu muss ich eine Funktion f (der Integrant, der die Form double (*)(double, void*) hat) definieren. Für den Aufruf der gsl-Integrationsmethode muss ich eine Struktur definieren, die einen Zeiger auf eine Funktion enthält (diese Struktur heißt gsl_function).Zeiger auf Elementfunktion eines Objekts

gsl_function F; 
F.function = &MyClass::my_f; 

Die Funktion f muss (von denen in der gleichen Klasse soll das Integrationsverfahren genannt werden) in einer Klasse implementiert werden. Wie kann ich den Zeiger oben richtig zuordnen, da die zweite Zeile nicht kompiliert und führt zu dem Fehler:

cannot convert ‘double (MyClass::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment. 

Hier ist die Definition von my_f

struct my_f_params { double a; double b;}; 

    double my_f (double x, void * p) { 
    struct my_f_params * params = (struct my_f_params *)p; 
    double a = (params->a); 
    double b = (params->b); 
    return 1.0/(sqrt(a * (1.0 + x)*(1.0 + x)*(1.0 + x) + (1-a) * std::pow((1.0 + x), (3.0 * (1.0 + b))))); 
    } 
+0

Sie müssen dort eine 'statische' Mitgliedsfunktion als Callback bereitstellen. Ich nehme an, der 'void *' Parameter kann (falsch) verwendet werden, um den 'this' Zeiger nach Bedarf zu übergeben. –

+0

Zeiger zu Mitgliedern sind keine normalen Zeiger. Sie müssen es in eine flache Funktion wickeln. Es gibt viele Beispiele für diese Technik auf SO. –

+1

Denken Sie über den 'void *' Parameter von 'gsl_function :: function' nach. Wofür könnte es möglicherweise verwendet werden? –

Antwort

1

which has to be of the form double (*)(double, void*)

Nicht statische Funktion Erklärungen Mitglied beinhalten der implizite Aufrufbereich Qualifier wie in der Fehlermeldung

double (MyClass::*)(double, void*) 
    // ^^^^^^^^^ 

angegeben Dies unterscheidet sich von der Callback-Funktionszeigerdefinition.

Was Sie wahrscheinlich mit einer solchen Schnittstelle tun können, ist die this Zeiger durch das void* Argument der Callback-Funktion übergeben:

class MyClass { 
    static double func(double d,void* thisPtr) { 
     MyClass* myClass = (MyClass*)thisPtr; 
     // do something 
    } 
}; 

Wie erwähnt in the documentation Sie die params wie in einer Wrapper-Klasse festlegen können:

class gsl_function_wrapper { 
public:  
    gsl_function_wrapper() { 
     F.function = &func; 
     F.params = this; 
    } 
private: 
    gsl_function F; 

    double a; 
    double b; 

    static double func(double d,void* thisPtr) { 
     gsl_function_wrapper* myWrapper = (gsl_function_wrapper*)thisPtr; 
     // do something with a and b 
     foo(d,myWrapper->a,myWrapper->b); 
    } 
}; 
+0

Bitte geben Sie an, wo Sie diese Lösung erhalten haben (nicht auf der GSL-Website). Mögliche richtige Quelle - https://Stackoverflow.com/a/18413206/2472169 –

Verwandte Themen