拥有C++成员函数的最佳方法是由C回调调用?

ker*_*aba 4 c++ struct function callback

给出一个典型的类:

struct Whatever
{
    void Doit();
};

Whatever w;

什么是通过基于C void*的回调(如pthread_create()或信号处理程序)调用成员函数的最佳方法?

pthread_t pid;

pthread_create(&pid, 0, ... &w.Doit() ... );

Ian*_*n G 6

大多数C回调允许指定参数,例如

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine)(void*), void *arg);
Run Code Online (Sandbox Code Playgroud)

所以你可以拥有

void myclass_doit(void* x)
{
  MyClass* c = reinterpret_cast<MyClass*>(x);
  c->doit();
}

pthread_create(..., &myclass_doit, (void*)(&obj));
Run Code Online (Sandbox Code Playgroud)


ker*_*aba 6

最简洁的解决方案是在所有代码共享的头文件中定义:

template <typename T, void (T::*M)()>
void* thunk(
    void* p)
{
    T* pt = static_cast<T*>(p);

    (pt->*M)();

    return 0;
}

您可能希望定义4个版本:thunk返回void和void *各一个,以及每个成员函数返回void和void的版本*.这样编译器可以匹配最好的编译器,具体取决于具体情况(事实上,如果一切都不匹配,它会抱怨.)

然后,每次遇到其中一种情况时,您只需输入以下内容:

pthread_create(&pid,0,&thunk <Whatever,&Whatever :: doit>,&w);

当方法是私有的时,这甚至可以工作,只要从类的代码中引用该方法即可.(如果没有,我不得不想知道为什么代码引用了私有方法.)