【问题标题】:g++ error : pthread_create() and pointer to member function [duplicate]g ++错误:pthread_create()和指向成员函数的指针[重复]
【发布时间】:2012-10-19 13:23:51
【问题描述】:

可能重复:
pthread Function from a Class

我正在尝试使用启动例程创建线程,但 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*) 转换为void* (*) (void*) 用于pthread_create 的参数3。

有什么想法吗?

【问题讨论】:

    标签: c++ pthreads iso


    【解决方案1】:

    您需要将 myFunction 声明为静态才能将其视为常规函数。

    【讨论】:

      【解决方案2】:

      您不能将常规函数成员用作线程例程。原因是这样的函数成员需要调用上下文 - this 对象指针,而 pthread 胆量是不可用的。

      使这样的函数成员static 或者只是释放函数。

      【讨论】:

        【解决方案3】:

        您不能将指针传递给非静态方法。您可能想要使用代理函数,将指向您的实例的指针作为参数传递给 pthread_create 并从那里进行 myFunction 调用

        【讨论】:

          【解决方案4】:

          正如编译器所说,你必须在 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);
            }
          }
          

          您还可以使用结构作为上下文,如果需要,您可以在其中传递此参数和其他参数。

          【讨论】:

            【解决方案5】:

            您可以将您的函数设为静态,也可以使用一些变通方法从您的类中调用该函数。

            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);
                }
            

            【讨论】:

              【解决方案6】:

              正如您的编译器所指定的 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();
              }
              

              但是如果您需要传递更多参数,您应该为其创建一个结构并在该结构中传递您的参数,但不要记住传递的结构必须保持有效,直到您的函数实际作为新线程调用。所以应该是全局或者动态分配的对象

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2017-06-29
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-12-03
                相关资源
                最近更新 更多