Ошибка g ++: pthread_create () и указатель на функцию-член

Возможный дубликат:
Функция pthread из класса

Я пытаюсь создать поток с подпрограммой запуска, но g ++ не нравится мой синтаксис.

class myClass
{
void* myFunction(void* myArg)
{
// some code, useless here
}

void start()
{
pthread_t thread_id;
int* fd;

//Some code, useless here.

pthread_create(&thread_id, 0, &myFunction, (void*) fd);
}
}

Во время компилятора g ++ говорит мне, что ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&myFunction',

Не может конвертировать void (myClass::*) (void*) в void* (*) (void*) для аргумента 3 из pthread_create,

Любая идея ?

2

Решение

Вам нужно будет объявить myFunction как статическую, чтобы ее можно было рассматривать как обычную функцию.

1

Другие решения

Вы не можете использовать обычный член функции в качестве подпрограммы потока. Причина в том, что такой член функции требует вызова контекста — this указатель объекта, который недоступен для pthread кишок.

Сделать такую ​​функцию членом static или просто бесплатная функция.

0

Вы не можете передать указатель на нестатический метод. Возможно, вы захотите использовать прокси-функцию, передав указатель на ваш экземпляр в качестве параметра pthread_create и сделав оттуда вызов myFunction

0

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

class myClass
{
static void startThread(void* context)
{
((myClass*)context)->myFunction()
}

void myFunction()
{
// some code, useless here
}

void start()
{
pthread_t thread_id;

//Some code, useless here.

pthread_create(&thread_id, 0, &startThread, this);
}
}

Также вы можете использовать структуру как контекст, в котором вы можете передать этот и другие аргументы, если это необходимо.

0

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

void *callMyFunction(void *f)
{
reinterpret_cast<myClass*>(f)->myFunction();
return (NULL);
}

class myClass
{
void* myFunction()
{
// some code, useless here
}

void start()
{
pthread_t thread_id;
int* fd;

//Some code, useless here.

pthread_create(&thread_id, 0, &callMyFunction, (void*) this);
}
}

Если вы хотите передать параметры myClass::myFunction, вам нужно будет создать небольшую структуру, как это

struct s_param
{
void  *ptr;
int   param1;
char  param2;
/* other variables */
};

callMyFunction станет

void *callMyFunction(void *bundle)
{
reinterpret_cast<myClass*>(bundle->ptr)->myFunction(bundle->param1, bundle->param2/*, ...*/);
return (NULL);
}
0

Как указано вашим компилятором pthread_create ожидать void* (*)(void*) но вы предоставляете функцию, которая имеет очень похожий, но другой синтаксис:

Каждая функция класса, который не является static имеет скрытый параметр с именем this типа class*так что теперь ваша функция void* (*)( class*, void* ) это не соответствует ожиданиям pthread_create, Вы должны предоставить функцию с той же архитектурой.

Также, если у вас была такая функция, как void* someFunction() в вашем классе это может быть соответствие для функции, которая ожидается pthread_createКонечно, это не разрешено компилятором, и на это также есть причина. Причина в соглашении о вызовах, означающем, как параметры, передаваемые в функцию, компилятору C ++ разрешено передавать this в реестрах! поэтому он не будет соответствовать функции, ожидаемой pthread_create, Это может быть решено некоторыми компиляторами, которые позволяют вам выбирать соглашение о вызовах для вашей функции, но это не является стандартным, поэтому лучше всего написать прокси-функцию как:

static void* my_thread_routine_proxy(void* param) {
static_cast<my_class*>(param)->my_thread_routine();
}

Но если вам нужно передать больше параметров, вы должны создать для него структуру и передать свои параметры в этой структуре, но не забывайте, что переданная структура должна оставаться действительной до тех пор, пока ваша функция на самом деле не будет вызвана как новый поток. Так что это должен быть глобальный или динамически размещаемый объект

0
По вопросам рекламы [email protected]