1

重複の可能性:
クラスからのpthread関数

pthread_create次の行が原因でコンパイルできない次のコードがあります。

void* gtk_functor::_threaded_run(void* win)
{
    Gtk::Window* w = static_cast<Gtk::Window*>(win);
    Gtk::Main::run(*w);
    delete w;
}

void gtk_functor::operator ()(Gtk::Window& win, bool threaded)
{
    if (threaded)
    {
        pthread_t t_num;
        pthread_create(&t_num, NULL, (void* (*)(void*))&gtk_functor::_threaded_run, static_cast<void*>(&win));
    }
    else
    {
        Gtk::Main::run(win);
    }
}

このgcc行:

g++ -o main 'pkg-config --cflags --libs sqlite3 gtkmm-3.0' -lpthread main.cpp

最後に、この出力でコンパイルします。

code/ui.cpp: In member function 'void ui::gtk_functor::operator()(Gtk::Window&, bool)':
code/ui.cpp:45:65: warning: converting from 'void* (ui::gtk_functor::*)(void*)' to 'void* (*)(void*)' [-Wpmf-conversions]

どうやらコードは正しく機能していません、私はが上げられsementation faultたときに取得します。if (threaded)

キャストでそれを知っていますが、メンバー関数をpthread_createに渡す正しい形式がわかりません。助言がありますか?

4

2 に答える 2

5

@ildjarnが示唆しているように、無料の関数を作成するだけです。

void * threaded_run(void * win)
{
    Gtk::Window * const w = static_cast<Gtk::Window*>(win);
    Gtk::Main::run(*w);
    delete w;
}

// ...

pthread_create(&t_num, NULL, threaded_run, &win);

関数は特定のgtk_functorオブジェクトの状態に依存しないため、メンバー関数にする意味はありません。


オブジェクトのメンバー関数を別のスレッドで呼び出す必要があるという架空の異なる世界では、通常は引数voidポインターを介して、オブジェクトのオブジェクト参照を何らかの方法で渡す必要があります。

struct Foo
{
    void * run() { /* ... use state ... */ }

    /* ... state ... */
};

Foo x;
pthread_t pt;

// start a new execution context with x.run():
pthread_create(&pt, NULL, FooInvoker, &x);

extern "C" void * FooInvoker(void * p)
{
    return static_cast<Foo*>(p)->run();
}

実際、より多くのコンテキスト情報をいくつかの補助構造にパッケージ化し、それへのvoidポインターをスレッド呼び出し関数に渡すこともできます。

于 2012-07-17T18:37:45.117 に答える
5

_threaded_run静的にしてみてください。ヘッダー内:

private:
  static void* _threaded_run(void*);

そして実装では:

void* gtk_functor::_threaded_run(void* win) {
  Gtk::Window* w = static_cast<Gtk::Window*>(win);
  Gtk::Main::run(*w);
  delete w;
}

次に、スレッドを作成するとき:

pthread_create(&t_num, NULL, &gtk_functor::_threaded_run, static_cast<void*>(&win));
于 2012-07-17T18:42:50.450 に答える