Creating a thread of a nonstatic member function?

16,140

Solution 1

You should privitize all of this information, except for perhaps a "start()" function. You would have a private static member function of your class as the target for the operating system's thread start, in "start()" pass the thread start method the "this" pointer of your object, cast it back to the object type in your static function which then calls your private main thread method on the object itself. Since the static function is a member of the class, it can use the private functions whereas if it weren't, it couldn't (without being a friend). I didn't compile/test this, but the idea is:

class MyObj {
private:
    void thread() {
            // this-> is valid here
    }

    static DWORD static_entry(LPVOID* param) {
        MyObj *myObj = (MyObj*)parm;
        myObj->thread();
        return 0;
    }

public:
    void start() {
        CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)static_entry, this, 0, NULL);
    }
};

Word of warning: Don't destroy the object while the thread is running! You may have to synchronize with a mutex or make sure the thread is joined at object destruction. You could also do a "delete this" at the end of thread() or a delete myObj at the end of static_entry if the caller of start() no longer manages the object.

Solution 2

Create a static function

static DWORD myFunctionCaller(LPVOID* param)  
{
  MyClass* myClass = static_cast<MyClass*>(param);
  myClass->MyFunction();
}

CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)myFunctionCaller, this, 0, NULL);

The downside is that you get a few floating static functions, but you can limit the scope easily, and that should prevent you from creating too many threads

Solution 3

C++ member function cannot called without class instance. Following code is one of my suggestion;

MyClass * instance = ...; // valid instance.
CreateThread(NULL, 0, StartRoutine, instance, 0, NULL);

DWORD WINAPI StartRoutine(LPVOID ptr) {
  static_cast<MyClass*>(ptr)->MyFunction();
}

The other suggestion is to declare member function with static keyword;

class MyClass {
  ...
  static DWORD WINAPI MyFunction();
  ...
}

In the second code, MyFunction cannot access class (non-static) member variables.

Share:
16,140
xcdemon05
Author by

xcdemon05

Updated on June 26, 2022

Comments

  • xcdemon05
    xcdemon05 almost 2 years

    If I have a member function. . .

    MyClass::MyFunction()
    {
        while(1)
        {
            //blah blah blah
        }
    }
    

    . . . and I try to create a thread of this function . . .

    CreateThread(Null, 0, (LPTHREAD_START_ROUTINE)MyFunction, NULL, 0, NULL);
    

    . . . I always get an error saying that (LPTREAD_START_ROUTINE)MyFunction is an invalid typecast and that I cannot create a thread of a nonstatic member function.

    I cannot make my function static because I use the this pointer several times which requires a nonstatic member function to do so.

    Is there any simple way to create a thread of a nonstatic member function?

    (I'm working in Visual Studio 2010, C++, MFC)