2016-12-03 8 views
-1

編集:は、別のクラスのメンバ関数への一つのクラスのメンバ関数を渡す - セグメンテーション違反 - mrmpi

私は、このための最小限のコードを実行しようとしたし、それが働きました。私は自分のコードに戻って何が間違っているのか理解しようとしています。この質問修正し、最小限のコードで将来の参照のためにそれを残して、最初から間違っていた(または私はそれを削除してください)

#include <iostream> 

class LibClass { 
public: 
     int mapLibClass(void (*callbackfunc) (int, void*)) { 
      std::cout << " in map " << std::endl; 
      callbackfunc(8,NULL); 
     } 
}; 

class MyClass { 
public: 
     LibClass* objLibClass; 

     MyClass(LibClass* objLibClass) : objLibClass(objLibClass) { } 

     void runLibClass() { 
      std::cout << "in runLibClass" << std::endl; 
      objLibClass -> mapLibClass(&MyClass::callbackfunc); 
     } 
     static void callbackfunc(int i, void* ptr) { 
      std::cout << "in callback" << std::endl; 
     } 
}; 

int main() { 
     LibClass* libClassObj = new LibClass(); 
     MyClass myClassObj(libClassObj); 
     myClassObj.runLibClass(); 
     return 0; 
} 

私はmrmpi図書館で働いている(とライブラリを知っている必要はありませんこの問題は以下で説明しますが、MapReduce for C++の実装です)。ライブラリーは、そのメンバ関数への引数としてコールバック関数を受け入れ:

class LibClass { 
public: 
    int mapLibClass(void (*callbackfunc)(int, KV*, void*)) { } 
}; 

今、私は(へのポインタ)LibClass型のメンバ変数を持っており、この変数通過のmapLibClass関数を呼び出す必要がある私自身のクラスを、持っています私のクラスの関数でそれに。

class MyClass { 
public: 
    LibClass* objLibClass; 

    MyClass(LibClass objLibClass) : objLibClass(objLibClass) { } 

    void runLibClass() { 
     //I have some extra lines here checking to make sure other member variables and also objLibClass are set correctly 
     objLibClass -> mapLibClass(&MyClass::callbackfunc); 
    } 

    static void callbackfunc(int i, KV* kv, void* ptr) { 
     //just an std::cout here to make sure I get into this function 
    } 
}; 

int main() { 
    LibClass* libClassObj = new LibClass(); 
    MyClass myClassObj(libClassObj); 
    myClassObj.runLibClass(); 
    return 0; 
} 

runLibClass関数内からmapLibClassが呼び出されるまではすべてがスムーズに進みます。 mapLibClassはいくつかのことをして、それがパラメータとして受け入れるコールバック関数を呼び出すことになっています。しかし、私は私のプログラムを実行しているときにコールバック関数を入力することはありませんが、私はセグメンテーション違反を取得します。

callbackfuncを非メンバ関数にすると、プログラムが正しく実行されるため、メンバ関数を渡すことと関係があります。私はドキュメントや他のSOの記事を読んだが、私のメンバーcallbackfuncは静的でなければならない(それはコンパイルされていない)か、boost :: bindとboost :: functionを使うべきである私はライブラリのソースコードを変更する)。私はsegfaultの原因を突き止めることはできません。私はこれに多くの時間を費やしたので、どんな助けも高く評価されます。ありがとう。

+1

はコンパイルされませんし、非会員と静的メンバ関数の間に違いはありませんhttp://ideone.com/trITGM – Stargateur

+2

を再現することはできません。明白なエラーを修正した後で、あなたの例は動作します(http://ideone.com/IJredv)。 [mcve]を投稿してください。 –

+0

申し訳ありません。私は最初のコメントの後に最小限のコードを書き始めました:http://ideone.com/70THz8 ...そして...それは今実行されます。私は他のどこかで問題を探すべきです。 – armen

答えて

-2

あなたはctorが値によってクラスの代わりにポインタを受け取るように見えます。 その理由は、ポインタがnullであるというエラーが発生するからです。あなたは、パラメータとしてメンバ関数を渡しているときに、別の宣言を持っている必要があります間

MyClass(LibClass * objLibClass) : objLibClass(objLibClass) {} 
+0

これはできません。 'MyClass(LibClass objLibClass):objLibClass(objLibClass){} 'はコンパイルされません。 – Stargateur

+1

コンパイラは悲鳴を上げるでしょう(おそらくキャストはありませんし、もしそれがポインタをゼロにしていなければ)、それはmvceを作成しようとしているopの誤植かもしれません。 – George

+0

私はそれがコンパイルされていない(Stargateurによって指摘された)ように実行するようにコードを変更しました。それが機能することを認識したので、問題は別の場所にあるはずです。申し訳ありません。 http://ideone.com/70THz8 – armen

-1


次の変更はあなたの問題を解決します。 以下に小さな例がありますが、これはあなたを助けるかもしれません。

#include <iostream> 
using namespace std; 

class A { 
public: 
    void xx() { cout << "xx" << endl; } 
}; 

void f(A &a, void (A::*x)()) { 
    (a.*x)(); 
    cout << "calling A xx" << endl; 
} 

int main() { 
    // your code goes here 
    A a; 
    f(a, &A::xx); 
    return 0; 
} 
+0

"メンバ関数をパラメータとして渡すとき、別の宣言が必要です。"何か? – George

+0

私はそれがコンパイルされていない(Stargateurによって指摘された)ように実行するようにコードを変更しました。それが機能することを認識したので、問題は別の場所にあるはずです。申し訳ありません。 ideone.com/70THz8 – armen

関連する問題