g++ error : pthread_create() and pointer to member function [duplicate]

心已入冬 提交于 2019-12-11 01:51:03

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!