I can't pass a pointer to method to the CreateThread function, of course. What should I do?
-
possible duplicate of [Simple example of threading in C++](http://stackoverflow.com/questions/266168/simple-example-of-threading-in-c) – George Stocker Jun 09 '11 at 16:19
-
Use CreateThread with caution, as it doesn't initialize the C (and possibly the C++) runtime for the new thread. – Jörgen Sigvardsson Jun 09 '11 at 22:55
-
Really? How to initialize the runtime manually? – KOLANICH Jul 16 '12 at 15:28
6 Answers
If using a class, some pattern like this usually works well:
.h
static UINT __cdecl StaticThreadFunc(LPVOID pParam);
UINT ThreadFunc();
.cpp
// Somewhere you launch the thread
AfxBeginThread(
StaticThreadFunc,
this);
UINT __cdecl CYourClass::StaticThreadFunc(LPVOID pParam)
{
CYourClass *pYourClass = reinterpret_cast<CYourClass*>(pParam);
UINT retCode = pYourClass->ThreadFunc();
return retCode;
}
UINT CYourClass::ThreadFunc()
{
// Do your thing, this thread now has access to all the classes member variables
}

- 10,462
- 8
- 53
- 69
I often do this:
class X {
private:
static unsigned __stdcall ThreadEntry(void* pUserData) {
return ((X*)pUserData)->ThreadMain();
}
unsigned ThreadMain() {
...
}
};
And then I pass this
as user data to the thread creator function (_beginthread[ex], CreateThread, etc)

- 4,839
- 3
- 28
- 51
The most common way is to create a Thread class that has a run() method and a start() method (these names borrowed from the Java Thread class). run() is a pure virtual that you overload in a class derived from Thread to do the actual work. The method start() internally calls CreateThread passing the this pointer via reinterpret_cast to void*. The Thread class has also a threadEntryPoint() static function that you pass to CreateThread. In threadEntryPoint() you do a reinterpret_cast back to Thread* and then call run() on it.
If there's one situation in which you just want a method of another class to be executed on a separated thread (without having to inherit from the Thread class) you can create a Thread-derived class that receives a pair object+method pointers in the constructor, and calls them in run(). To ease things up, make this derived class a template. Also take a look on boost for functor adaptors.

- 15,819
- 5
- 38
- 51
-
thanks. as i understood, i only nedd to add one static function to my class and one method to start, threadEntryPoint functionality will be realized in the statiс method. – KOLANICH Jun 09 '11 at 16:03
-
Yes, if you want to do this once-only it's as simple as that. If you want to reuse it in other places, it'd be better to isolate the code in a separated class. – Fabio Ceconello Jun 09 '11 at 16:08
CreateThread won't take a pointer to a member function. You can wrap the member function in a static function which takes the object pointer through lpParameter.

- 6,785
- 6
- 42
- 74
CreateThread's lpStartAddress is of type DWORD (WINAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter) and this is incompatible with the member function since the member function has an implicit this pointer in its signature. So create a static function and pass the class pointer as the argument to the thread function.

- 1,199
- 1
- 8
- 13
If you are talking about Native CreateThread
Method you would probably need to do following
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&MyThreadProc,NULL,NULL,&threadId);
Where your callback method is defined as
void MyThreadProc()
{
}

- 10,118
- 3
- 39
- 52
-
3You don't want to do this - the cast here is a problem: generally speaking, you should never cast a function just to make things work. Instead you should pass MyThreadProc without a cast, and then change void MyThreadProc() to be DWORD WINAPI MyThreadProc(LPVOID), which is what CreateThread is expecting. Passing a function with a different number or type of params or calling convention than an API is expecting can lead to a messed-up stack. – BrendanMcK Jun 09 '11 at 22:05