Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ class: pointer to a non-static func

This is my last question. I try to improve my class Thread. Constructor receives pointer to the function, that must run in a new thread.

class Thread { 
    public:
     Thread(void (*p)()) {
        pf=p;
      }
     ~Thread () {}
    void StartThread() {
     hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, NULL, 0, &threadID); 
    }
    private: 
     void (*pf)();
     HANDLE hThread; 
     unsigned threadID;
     static unsigned WINAPI ThreadProc(LPVOID lpParam) {
      (*pf)(); //error C2597 illegal reference to non-static member
      return 0; 
     }
    }; 

In ThreadProc I need to call TimerFunc.

void TimerFunc () {
    i++;
}

Example of usage this class:

Thread *timer; 
timer = new Thread(TimerFunc);  
timer->StartThread();

So it doesn't work. Please somebody tell me, if this class is foolish. May be it is a bad idea to send pointer to func which is situated outside class?? Thank you.

Thanks very much for your advices! Now it works!

class Thread { 
public:
    Thread(void (*p)()) {
        gg.pf=p;
    }
    ~Thread ();
    void StartThread() {
     hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, this, 0, &threadID); 
    }
private: 
    struct mm {
        Thread *pThread; 
        void (*pf)();
    } gg;
    HANDLE hThread; 
    unsigned threadID; 
    static unsigned WINAPI ThreadProc(LPVOID lpParam) {
        mm hh; 
        hh.pThread=static_cast<Thread*> (lpParam);
        hh.pf=hh.pThread->gg.pf;
        hh.pf();
        return 0; 
    }
}; 

What do you think? Is it correct choice?

like image 753
Girl_Developer Avatar asked Jan 19 '26 14:01

Girl_Developer


1 Answers

As the outhers pointed out, the problem is that a static method cannot access non-static members. The usual way to do something like this is to pass the object as parameter to the thread start routine, e.g.:

class Thread { 
public:
    Thread(void (*p)()) {
        pf=p;
    }
    ~Thread () {}
    void StartThread() {
        // Pass this as argument to ThreadProc
        hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, this, 0, &threadID); 
    }
private: 
    void (*pf)();
    HANDLE hThread; 
    unsigned threadID;
    static unsigned WINAPI ThreadProc(LPVOID lpParam) {
        // Get the passed Thread object
        Thread *pThread = static_cast<Thread*> (lpParam);
        pThread->pf();
        return 0; 
    }
}; 
like image 79
king_nak Avatar answered Jan 21 '26 06:01

king_nak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!