考虑以下类
class Foo
{
public:
void* func(void* arg)
{
// how to pass this function to pthread...?!
}
}
稍后我想将func()
传递给pthread_create()
,而不是函数:
int main()
{
char * msg = "Hi dude";
Foo * ins = new Foo();
pthread_t pt;
// how to pass ins->func instead of a function?
pthread_create( &pt, NULL, ins->func, (void*)msg );
}
提前谢谢。
"通常"的方法是,将对象和所有函数参数打包到一个结构中,在堆上分配此结构,将此结构的实例传递给具有 C 绑定的函数,并让该函数调用对象成员函数:
struct wrap {
char * msg;
Foo ins;
wrap( char* m, const Foo& f ) : msg(m), ins(f) {}
};
extern "C" void* call_func( void *f )
{
std::auto_ptr< wrap > w( static_cast< wrap* >( f ) );
w->ins.func(w->msg);
return 0;
}
int main() {
wrap* w = new wrap( "Hi dude", Foo() );
pthread_t pt;
pthread_create( &pt, NULL, call_func, w );
}
它不能按照您尝试的方式工作C++因为成员函数获取作为其第一个参数传递的对象this
指针。如果处于C++模式,编译器会隐式执行此操作。
但是,pthread_create()
是一个 C 函数。它的第三个参数是"指向将void *
作为参数(并返回void *
)的函数的指针"。一旦进入pthread_create()
,就没有this
,没有信息this
应该隐式传递为第一个参数......并且成员函数的调用方式与预期调用的方式非常不同 - 您遇到了各种各样的麻烦。
这就是为什么pthread_create()
只适用于使用"C"链接的函数:全局函数和静态成员函数(两者都不使用this
指针)。
Torsten有一个很好的方法来绕过这个限制。我只是想详细说明一下问题的技术背景。
一种方法是将函数声明为静态
#include <iostream>
#include <pthread.h>
class Foo {
public:
static void* func(void* arg) {
char *test = (char *) arg;
std::cout << test << std::endl;
}
};
int main() {
char * msg = "Hi dude";
Foo ins;
pthread_t pt;
pthread_create( &pt, NULL, ins.func, (void*)msg );
pthread_join(pt, NULL);
return 0;
}