3

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)

xcdemon05
  • 1,372
  • 5
  • 25
  • 49
  • http://stackoverflow.com/questions/6841044/boost-library-and-createthread-win-api – Xyand Feb 07 '13 at 14:39
  • This topic is covered many times on SO. [C++ Thread in member function](http://stackoverflow.com/q/7170269/), [Create thread is not accepting the member function](http://stackoverflow.com/q/2891926/), [run threads of class member function in c++](http://stackoverflow.com/q/4666635/)... A quick search for "[thread member function](http://stackoverflow.com/search?q=thread+member+function)" turns up many many hits on this site. – Raymond Chen Feb 07 '13 at 14:55

3 Answers3

4

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.

mark
  • 5,269
  • 2
  • 21
  • 34
2

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.

kamae
  • 1,825
  • 1
  • 16
  • 21
  • This will not work because inside the thread I use the _this_ pointer referring to the window. My program will crash when it gets to that line. – xcdemon05 Feb 07 '13 at 14:59
  • The pointer `instance` should point correct instance of `MyClass`. – kamae Feb 07 '13 at 15:06
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

Eric
  • 19,525
  • 19
  • 84
  • 147
  • To avoid floating static functions, you can also define the static function inside your class as a static function. – mfc Feb 07 '13 at 16:14