2017-02-11 20 views
0

関数をgslと統合したいと思います。そのために私は関数fを定義しなければなりません(これは、double (*)(double, void*)の形式でなければなりません)。 gslの統合メソッドの呼び出しでは、関数へのポインタを含む構造体を定義する必要があります(この構造体はgsl_functionと呼ばれています)。オブジェクトのメンバ関数へのポインタ

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

関数fは(統合手順が呼び出されるべきと同じクラスに)クラスに実装されなければなりません。ここで

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

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

コールバックとして「静的」メンバー関数を用意する必要があります。 'void *'パラメータは、必要に応じて 'this'ポインタを渡すために(誤って)使われることがあると思います。 –

+0

メンバへのポインタは通常のポインタではありません。フラットな関数の中にラップする必要があります。この技術の多くの例がSOにあります。 –

+1

'gsl_function :: function'の' void * 'パラメータについて考えてみましょう。それはおそらく何のために使われますか? –

答えて

1

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

非静的メンバ関数宣言の定義が伴う:どのように私は、2行目は、コンパイルしてエラーにつながるされていないため、正しく上にポインタを割り当てることができますエラーメッセージに記載されている暗黙的な呼び出しスコープ修飾子

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

これは、コールバック関数のポインタ定義とは異なります。

あなたはおそらくそのようなインタフェースで何ができるか、コールバック関数のvoid*引数を通じてthisポインタを渡すことです:あなたはラッパークラスにそのようなのparamsを設定することができますin the documentation述べたように

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

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

このソリューションを入手した場所に正確な引用をしてください(GSLのウェブサイトには掲載されていません)。可能な正しいソース - https://stackoverflow.com/a/18413206/2472169 –

関連する問題