我正在尝试使用启动例程创建一个线程,但是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*)
的参数3无法将void* (*) (void*)
转换为pthread_create
。
有什么想法吗?
答案 0 :(得分:1)
您需要将myFunction声明为静态,以便将其视为常规函数。
答案 1 :(得分:0)
您不能将常规函数成员用作线程例程。原因是这样的函数成员需要调用上下文 - this
对象指针,这对于pthread
胆量不可用。
创建这样的函数成员static
或只是自由函数。
答案 2 :(得分:0)
您无法将指针传递给非静态方法。您可能希望使用代理函数,将指针作为参数传递给pthread_create并从那里调用myFunction
答案 3 :(得分: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);
}
}
此外,您可以使用结构作为上下文,您可以根据需要传递此参数和其他参数。
答案 4 :(得分: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);
}
答案 5 :(得分: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();
}
但是如果你需要传递更多的参数,你应该为它创建一个结构并在该结构中传递你的参数,但是不记得传递的结构必须保持有效,直到你的函数实际上被称为新线程。所以它应该是一个全局或动态分配的对象