给出一个典型的类:
struct Whatever { void Doit(); }; Whatever w;
什么是通过基于C void*的回调(如pthread_create()或信号处理程序)调用成员函数的最佳方法?
pthread_t pid; pthread_create(&pid, 0, ... &w.Doit() ... );
Ian G.. 6
大多数C回调允许指定参数,例如
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
所以你可以拥有
void myclass_doit(void* x) { MyClass* c = reinterpret_cast(x); c->doit(); } pthread_create(..., &myclass_doit, (void*)(&obj));
keraba.. 6
最简洁的解决方案是在所有代码共享的头文件中定义:
templatevoid* thunk( void* p) { T* pt = static_cast (p); (pt->*M)(); return 0; }
您可能希望定义4个版本:thunk返回void和void *
各一个,以及每个成员函数返回void和void的版本*
.这样编译器可以匹配最好的编译器,具体取决于具体情况(事实上,如果一切都不匹配,它会抱怨.)
然后,每次遇到其中一种情况时,您只需输入以下内容:
pthread_create(&pid,0,&thunk
当方法是私有的时,这甚至可以工作,只要从类的代码中引用该方法即可.(如果没有,我不得不想知道为什么代码引用了私有方法.)
大多数C回调允许指定参数,例如
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
所以你可以拥有
void myclass_doit(void* x) { MyClass* c = reinterpret_cast(x); c->doit(); } pthread_create(..., &myclass_doit, (void*)(&obj));
最简洁的解决方案是在所有代码共享的头文件中定义:
templatevoid* thunk( void* p) { T* pt = static_cast (p); (pt->*M)(); return 0; }
您可能希望定义4个版本:thunk返回void和void *
各一个,以及每个成员函数返回void和void的版本*
.这样编译器可以匹配最好的编译器,具体取决于具体情况(事实上,如果一切都不匹配,它会抱怨.)
然后,每次遇到其中一种情况时,您只需输入以下内容:
pthread_create(&pid,0,&thunk
当方法是私有的时,这甚至可以工作,只要从类的代码中引用该方法即可.(如果没有,我不得不想知道为什么代码引用了私有方法.)