Функция-член приведения для вызова create_pthread () - PullRequest
3 голосов
/ 26 июля 2011

Я хочу прекратить предупреждение

server.cpp: 823: предупреждение: преобразование из 'void * (ClientHandler :: ) ()' в 'void () (void )'

при звонке:

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

, где handle() является функцией-членом ClientHandler:

void* ClientHandler::handle();

У меня проблемы с расшифровкой сообщения типа функции от компилятора.

Вопрос:

  • Должен ли я изменить интерфейс handle()? Можно ли вообще избавиться от кастинга?
  • Должен ли я изменить актерский состав? На что именно?
  • Что-то совершенно другое?

Ответы [ 3 ]

7 голосов
/ 26 июля 2011

Вы не можете сделать это напрямую, указатели на функции-члены не являются простыми указателями на функции и не могут быть перенаправлены на C обратные вызовы напрямую.

Вам понадобится один уровень косвенности:

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

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

См. Указатели на элементы FAQ C ++ для получения дополнительной информации / альтернатив.

Для достоверности приведения в callHandle,см. этот вопрос .Вы несете единоличную ответственность за то, чтобы убедиться, что handle все еще жив и здоров, когда вызывается, конечно, callHandle (и за то, что он фактически указывает на ClientHandle).

3 голосов
/ 26 июля 2011

Вам необходимо передать статическую 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" */
1 голос
/ 26 июля 2011

Если вы хотите вызвать метод ClientHandler::handle из определенного экземпляра класса ClientHandler, он, к сожалению, немного сложнее, чем ваш пример, поскольку указатели на функции-члены отличаются от указателей на функции в целом. См. здесь для полного описания того, что необходимо сделать для создания pthreads таким способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...