用于create_pthread()调用的cast成员函数

时间:2011-07-26 07:23:35

标签: c++ c pthreads function-pointers member-function-pointers

我想停止警告

  

server.cpp:823:警告:从'void *(ClientHandler :: )()'转换为'void )(void )'

电话中的

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

其中handle()ClientHandler的成员函数:

void* ClientHandler::handle();

我很难从编译器解密函数类型的消息。

问题是:

  • 我应该更改handle()界面吗?我可以摆脱整体播放吗?
  • 我应该更改演员吗?到底是什么?
  • 完全不同的东西?

3 个答案:

答案 0 :(得分:7)

你不能直接这样做,指向成员函数的指针不是函数的简单指针,不能直接移交给C回调。

您需要一个级别的间接:

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

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

有关更多信息/替代方案,请参阅C ++常见问题解答的Pointers to members部分。

有关callHandle中演员表的有效性,请参阅this question。您自行负责确保当handle被调用时callHandle仍然存在且很好(并且实际上它指向ClientHandle)。

答案 1 :(得分: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" */

答案 2 :(得分:1)

如果您希望从ClientHandler::handle类的特定实例调用方法ClientHandler,遗憾的是它比您的示例复杂一点,因为指向成员函数的指针与指向函数的指针不同一般来说。有关以这种方式创建pthreads需要执行的操作的完整说明,请参阅here