Функция-член приведения для вызова create_pthread()

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

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

в вызове:

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

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

void* ClientHandler::handle();

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

Вопрос в том:

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

3 ответа

Решение

Вы не можете сделать это напрямую, указатели на функции-члены не являются простыми указателями на функции и не могут быть переданы 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 называется, конечно (и за то, что это на самом деле указывает на 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::handle из конкретного экземпляра ClientHandler Класс, к сожалению, это немного сложнее, чем ваш пример, так как указатели на функции-члены отличаются от указателей на функции в целом. Смотрите здесь для полного описания того, что необходимо сделать для создания pthreads таким образом.

Другие вопросы по тегам