3

警告を止めたい

server.cpp:823:警告:'void *(ClientHandler :: )()'から'void)(void)'に変換しています

通話中:

pthread_create(th, NULL,
    (void* (*)(void*)) &ClientHandler::handle,
    (void *) clientHandler);

ここhandle()で、のメンバー関数は次のClientHandlerとおりです。

void* ClientHandler::handle();

コンパイラからの関数型メッセージを解読するのに苦労しています。

質問は:

  • handle()インターフェイスを変更する必要がありますか?全体的にキャストを取り除くことはできますか?
  • キャストを変更する必要がありますか?正確には何に?
  • 何か完全に違う?
4

3 に答える 3

7

Cこれを直接行うことはできません。メンバー関数へのポインターは関数への単純なポインターではなく、コールバックに直接渡すことはできません。

1レベルの間接参照が必要です。

void callHandle(void *data) {
  ClientHandle *h = static_cast<ClientHandle*>(data);
  h->handle();
}

pthread_create(th, 0, &callHandle, static_cast<void*>(handle));

詳細/代替案については、C++FAQの「メンバーへのポインタ」セクションを参照してください。

キャストの有効性については、この質問callHandleを参照してください。もちろん、呼び出されたときにそれがまだ生きていてうまくいくことを確認する責任はあなただけにあります(そしてそれが実際にを指しているという事実について)。handlecallHandleClientHandle

于 2011-07-26T07:30:55.463 に答える
3

このシグニチャで指定されているように、静的cdecl関数をに渡す必要があります。pthread_create

void* handler(void* data);

オプションの引数を使用して、ClientHandlerオブジェクトをスレッドに渡すことができます。

class ClientHandler()
{
public:
  static void* handle(void* data);
}

extern "C" {

void* ClientHandler::handle(void* data)
{
  ClientHandler* handler = reinterpret_cast<ClientHandler*>(data)
  // fancy stuff with handler object here
}

} /* extern "C" */
于 2011-07-26T07:28:35.010 に答える
1

ClientHandler::handleクラスの特定のインスタンスからメソッドを呼び出す場合は、ClientHandlerメンバー関数へのポインターが一般的な関数へのポインターとは異なるため、残念ながら例よりも少し複雑です。このような方法でpthreadを作成するために実行する必要があることの完全な説明については、ここを参照してください。

于 2011-07-26T07:29:02.123 に答える