Using function pointers in c++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • MattWilson.6185@gmail.com

    Using function pointers in c++

    Hi!

    I have had this problem several times before, and each time I have
    been turned back forced to find another way. But not this time...

    How can you cast a Class::* into a void *.

    For this example I am using pthread and to start a thread you need to
    pass it a void* (*)(void*)

    however I have the run function inside a class:

    class ThreadBase {
    public:
    ThreadBase() {}
    virtual void run() = 0;
    void start_thread() { pthread_create( &__thread_id , 0 ,this-
    >run , 0 ); }
    void join_thread();
    private:
    pthread_t __thread_id;
    };

    Now if you inherit from this class and make a run function and call
    start_thread you recieve this error:

    error: cannot convert void (ThreadBase::*) () to void* (*)(void*)

    This doesn't only happen with classes, if you put a function in a
    namespace I believe you get a similar error.

    Is there a solution, or must you solve the problem another way?

    Thanks allot!

    Matt

  • John Harrison

    #2
    Re: Using function pointers in c++

    MattWilson.6185 @gmail.com wrote:
    Hi!
    >
    I have had this problem several times before, and each time I have
    been turned back forced to find another way. But not this time...
    >
    How can you cast a Class::* into a void *.
    >
    For this example I am using pthread and to start a thread you need to
    pass it a void* (*)(void*)
    >
    however I have the run function inside a class:
    >
    class ThreadBase {
    public:
    ThreadBase() {}
    virtual void run() = 0;
    void start_thread() { pthread_create( &__thread_id , 0 ,this-
    >
    >>run , 0 ); }
    >
    void join_thread();
    private:
    pthread_t __thread_id;
    };
    >
    Now if you inherit from this class and make a run function and call
    start_thread you recieve this error:
    >
    error: cannot convert void (ThreadBase::*) () to void* (*)(void*)
    >
    This doesn't only happen with classes, if you put a function in a
    namespace I believe you get a similar error.
    >
    Is there a solution, or must you solve the problem another way?
    >
    Thanks allot!
    >
    Matt
    >
    Of course there is a way.

    Your must pass a function of the correct type to pthread_create but
    there is no reason that function cannot call ThreadBase::run

    Like this

    void run_my_thread(v oid* my_this)
    {
    ((ThreadBase*)m y_this)->run();
    }

    void ThreadBase::sta rt_thread()
    {
    pthread_create( &__thread_id , 0 , run_my_thread , this );
    }

    This is a FAQ of course,



    john

    Comment

    • red floyd

      #3
      Re: Using function pointers in c++

      MattWilson.6185 @gmail.com wrote:
      Hi!
      >
      I have had this problem several times before, and each time I have
      been turned back forced to find another way. But not this time...
      >
      How can you cast a Class::* into a void *.
      >
      For this example I am using pthread and to start a thread you need to
      pass it a void* (*)(void*)
      >
      however I have the run function inside a class:
      >
      class ThreadBase {
      public:
      ThreadBase() {}
      virtual void run() = 0;
      void start_thread() { pthread_create( &__thread_id , 0 ,this-
      >run , 0 ); }
      void join_thread();
      private:
      pthread_t __thread_id;
      };
      >
      Now if you inherit from this class and make a run function and call
      start_thread you recieve this error:
      >
      error: cannot convert void (ThreadBase::*) () to void* (*)(void*)
      >
      This doesn't only happen with classes, if you put a function in a
      namespace I believe you get a similar error.
      >
      Is there a solution, or must you solve the problem another way?
      >
      In short, you can't, nor do you want to.


      Comment

      • red floyd

        #4
        Re: Using function pointers in c++

        John Harrison wrote:
        >
        Like this
        >
        void run_my_thread(v oid* my_this)
        {
        ((ThreadBase*)m y_this)->run();
        }
        Better is

        extern "C" void run_my_thread(v oid* my_this)
        {
        static_cast<Thr eadBase*>(my_th is)->run();
        }

        In general, most C style callback interfaces generally require C linkage.
        >
        void ThreadBase::sta rt_thread()
        {
        pthread_create( &__thread_id , 0 , run_my_thread , this );
        }
        >
        >

        Comment

        • Ian Collins

          #5
          Re: Using function pointers in c++

          MattWilson.6185 @gmail.com wrote:
          Hi!
          >
          I have had this problem several times before, and each time I have
          been turned back forced to find another way. But not this time...
          >
          How can you cast a Class::* into a void *.
          >
          For this example I am using pthread and to start a thread you need to
          pass it a void* (*)(void*)
          >
          however I have the run function inside a class:
          >
          class ThreadBase {
          public:
          ThreadBase() {}
          virtual void run() = 0;
          void start_thread(){ pthread_create( &__thread_id , 0, this->run, 0 );}
          You just can't do this. The pthread_create function expects a C
          function of the form void* (*)(void*). Any class member function will
          have a hidden this parameter, which isn't a void*. A class member
          function has C++ linkage.

          The only correct form is to declare a function extern "C" and pass that
          function to pthread_create.

          extern "C" void start( void* );

          void start( void *p )
          {
          ThreadBase *base = static_cast<Thr eadBase*>(p);
          base->run();
          }

          --
          Ian Collins.

          Comment

          • MattWilson.6185@gmail.com

            #6
            Re: Using function pointers in c++

            extern "C" void start( void* );
            >
            void start( void *p )
            {
            ThreadBase *base = static_cast<Thr eadBase*>(p);
            base->run();
            >
            }
            >
            --
            Ian Collins.
            Thank you all very much! Worked like a charm.

            Matt

            Comment

            Working...