Pointer to member function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dan Smithers

    Pointer to member function

    I want to implement a C++ wrapper to C code that requires a function
    pointer to be passed in. Specifically, I want a wrapper for pthread that
    clients can use as a base class.

    Is there a way of passing a non-static member function in that will do
    this?

    In the following code, if I use the static k_main then it builds and
    runs, but the derived class uses the implementation in CMyThread.

    If I use a virtual member function, I get a compile error:
    thread2.cpp:21: error: argument of type ‘void* (CMyThread::)(v oid*)’
    does not match ‘void* (*)(void*)’

    Presumably this is because the member function pointer still expect the
    this parameter when it is called.

    I have thought of an alternative way that requires the CMyThread
    constructor to pass the this pointer as an additional argument that is
    then used in k_main to call the member function. It just looks really
    horrible.


    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>

    class CMyThread
    {
    protected:
    pthread_t m_thread;
    void *m_args;

    static void *k_main( void *ptr );
    virtual void *m_main( void *ptr );
    public:
    CMyThread(char *name);
    virtual ~CMyThread();
    };

    CMyThread::CMyT hread(char *args)
    : m_args(args)
    {
    int rc = pthread_create( &m_thread, NULL, m_main, (void *)args);
    }

    CMyThread::~CMy Thread()
    {
    pthread_join( m_thread, NULL);
    }

    void *CMyThread::k_m ain(void *args)
    {
    char *message;
    message = (char *) args;
    printf("Base Static %s \n", message);
    }

    void *CMyThread::m_m ain(void *args)
    {
    char *message;
    message = (char *) args;
    printf("Base Virtual %s \n", message);
    }

    class CMyDerivedThrea d : public CMyThread
    {
    protected:
    static void *k_main( void *ptr );
    virtual void *m_main( void *ptr );

    public:
    CMyDerivedThrea d(char *name);
    virtual ~CMyDerivedThre ad();
    };

    CMyDerivedThrea d::CMyDerivedTh read(char *args)
    : CMyThread(args)
    {
    }

    CMyDerivedThrea d::~CMyDerivedT hread()
    {
    }

    void *CMyDerivedThre ad::k_main(void *args)
    {
    char *message;
    message = (char *) args;
    printf("Derived Static %s \n", message);
    }

    void *CMyDerivedThre ad::m_main(void *args)
    {
    char *message;
    message = (char *) args;
    printf("Derived Virtual %s \n", message);
    }

    main()
    {
    pthread_t thread1, thread2;
    char *message1 = "Thread 1";
    char *message2 = "Thread 2";

    CMyThread t1(message1);

    CMyThread t2(message2);

    CMyDerivedThrea d("Thread 3");

    exit(0);
    }

  • tragomaskhalos

    #2
    Re: Pointer to member function

    On Jun 26, 3:12 pm, Dan Smithers <dsmith...@talk talk.netwrote:
    I want to implement a C++ wrapper to C code that requires a function
    pointer to be passed in. Specifically, I want a wrapper for pthread that
    clients can use as a base class.
    >
    Is there a way of passing a non-static member function in that will do
    this?
    >
    See http://www.parashift.com/c++-faq-lit...o-members.html



    Comment

    • kamit

      #3
      Re: Pointer to member function

      Check out boost::thread.

      On Jun 26, 12:17 pm, tragomaskhalos <dave.du.verg.. .@logicacmg.com >
      wrote:
      On Jun 26, 3:12 pm, Dan Smithers <dsmith...@talk talk.netwrote:
      >
      I want to implement a C++ wrapper to C code that requires a function
      pointer to be passed in. Specifically, I want a wrapper for pthread that
      clients can use as a base class.
      >
      Is there a way of passing a non-static member function in that will do
      this?
      >
      Seehttp://www.parashift.c om/c++-faq-lite/pointers-to-members.html

      Comment

      • James Kanze

        #4
        Re: Pointer to member function

        Dan Smithers wrote:
        James Kanze wrote:
        int rc = pthread_create( &m_thread, NULL, m_main, (void *)args);
        If this compiles, your compiler is broken.
        It didn't
        And replacing m_main
        with k_main shouldn't change anything here.
        It works with g++.
        That's a known bug in g++.

        [...]
        CMyThread::~CMy Thread()
        {
        pthread_join( m_thread, NULL);
        pthread_join can block. I'm not sure its a good idea to
        call it from a destructor. (Destructors are called during
        stack walkback, in case of an exception. Which is generally
        a context where you don't want to block for an indefinite
        time.)
        I'll have to think of a way of tidying up if exceptions are
        thrown.
        It is a problem:-). And I don't know of a good solution.
        (Boost detaches the thread, which is even worse than doing the
        join.) What you want to do is to force the other thread to
        terminate as rapidly as possible, and then join. But at least
        at present, pthread_cancel doesn't work (portably) in C++, and
        even if it did, it's largely advisory, at least in some of it's
        aspects.
        }
        --
        James Kanze (GABI Software) email:james.kan ze@gmail.com
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

        Comment

        Working...