问题
Possible Duplicate:
pthread Function from a Class
I am trying to create a thread with a start routine, but g++ does not like my syntax.
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);
}
}
During compilator, g++ tells me that ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&myFunction'
.
It cannot convert void (myClass::*) (void*)
to void* (*) (void*)
for argument 3 of pthread_create
.
Any idea ?
回答1:
You'll need to declare myFunction as static for it to be treated as a regular function.
回答2:
You cannot use regular function member as thread routine. The reason is that such function member requires calling context - this
object pointer which is unavailable for pthread
guts.
Make such function member static
or just free function.
回答3:
You connot pass a pointer to a non static method. You may want to use a proxy function, passing the pointer to your instance as a parameter to pthread_create and make the myFunction call from there
回答4:
As compiler said you have to use a static function with pthread, something like this should work :
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);
}
}
Also you can use a struct as the context in which you can pass this and other arguments if needed.
回答5:
You can either make your function static, or you can use a little workaround to call the function from your class.
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);
}
}
If you want to pass parameters to myClass::myFunction
, you will need to create a little structure like this
struct s_param
{
void *ptr;
int param1;
char param2;
/* other variables */
};
callMyFunction
would become
void *callMyFunction(void *bundle)
{
reinterpret_cast<myClass*>(bundle->ptr)->myFunction(bundle->param1, bundle->param2/*, ...*/);
return (NULL);
}
回答6:
As specified by your compiler pthread_create
expect a void* (*)(void*)
but you provide a function that has a very similar but different syntax:
Each function of a class that is not static
has a hidden parameter named this
of type class*
, so now your function is void* (*)( class*, void* )
that is not a match for what expected by pthread_create
. You should provide a function with same architecture.
Also if you had a function like void* someFunction()
in your class it could be a match for function that expected by pthread_create
, of course it is not allowed by compiler and it also has a reason. The reason is calling convention, meaning how parameters passed to a function, C++ compiler allowed to pass this
in the registers! so it won't match with function that expected by pthread_create
. This can be solved by some compilers that allow you to select calling convention of your function, but it is not standard, so best approach is to write a proxy function as:
static void* my_thread_routine_proxy(void* param) {
static_cast<my_class*>(param)->my_thread_routine();
}
But if you need to pass more parameters you should create an structure for it and pass your parameters in that structure, but do not remember that passed structure must remain valid until your function actually called as a new thread. So it should be a global or dynamically allocated object
来源:https://stackoverflow.com/questions/12975232/g-error-pthread-create-and-pointer-to-member-function