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回调。

您将需要一级间接:

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

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

有关更多信息/替代方案,请参阅 C++FAQ 的指向成员部分。

有关演员表的有效性callHandle,请参阅此问题。当然,您全权负责确保它在被调用handle时仍然活着并且callHandle完好无损(以及它实际上指向 a 的事实ClientHandle)。

于 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 回答