为create_pthread()调用强制转换成员函数

Cast member function for create_pthread() call

本文关键字:转换 成员 函数 调用 create pthread      更新时间:2023-10-16

我想停止警告

server.cpp: 823:警告:从"void * (ClientHandler:: )()"到"空白 ()(空白)

:

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

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

void* ClientHandler::handle();

我很难从编译器中破译函数类型消息。

问题是:

  • 我应该改变handle()接口吗?我可以摆脱铸造整体吗?
  • 我应该改变演员吗?到底是什么?
  • 完全不同的东西?

你不能直接这样做,成员函数的指针不是普通的函数指针,不能直接交给C回调。

你需要一个间接层次:

void callHandle(void *data) {
  ClientHandle *h = static_cast<ClientHandle*>(data);
  h->handle();
}
pthread_create(th, 0, &callHandle, static_cast<void*>(handle));

参见c++常见问题解答的成员指针一节了解更多信息。

关于callHandle中强制转换的有效性,请参见这个问题。当然,当callHandle被调用时,您唯一负责确保handle仍然存活并且运行良好(并且它实际上指向ClientHandle)。

您需要将静态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" */

如果您希望从ClientHandler类的特定实例调用ClientHandler::handle方法,不幸的是,它比您的示例要复杂一点,因为指向成员函数的指针与指向一般函数的指针不同。关于以这种方式创建pthread需要做什么的完整描述,请参阅此处。