user1502256
user1502256

Reputation:

Create new thread in class (windows)

I want to create a new thread in a class. The problem is when I need to pass a pointer to the function that will be used in the new thread. I am unable to pass a pointer to the function. A class function under the hood is basically this right?

void foo (this);

Then why does this code refuse to compile?

class TimeClass
{
private:
    DWORD   dwThreadId;
    HANDLE  hThread;

    LPTHREAD_START_ROUTINE Timer ();
public:
    TimeClass ();
};

TimeClass::TimeClass ()
{
    dwThreadId = CreateThread (NULL, 0, Timer, this, 0, &dwThreadId);
}

Upvotes: 1

Views: 1665

Answers (3)

ScottMcP-MVP
ScottMcP-MVP

Reputation: 10425

The signature of a thread function must be

DWORD WINAPI ThreadProc(LPVOID param);

An ordinary (i.e. nonstatic) C++ member function does not have the WINAPI calling convention so it cannot be used as a thread function. If you declare the member function as static then it can be used as a thread function:

static DWORD WINAPI ThreadProc(LPVOID param);

Upvotes: 2

vines
vines

Reputation: 5225

A class function under the hood is basically this right?

void foo (this);

Generally, no. It is what the compiler decides it to be, and there may be all kinds of 'non-virtual thunks', inlines, etc. The compiler is allowed to optimize the program in any way that doesn't change the program's behaviour, and such implementation details are not defined by the standard. That's why what you're trying to do is UB, and your best bet here (IMHO) would be something like:

extern "C" wrapper(void * p)
{
    static_cast<TimeClass*>(p)->whatever();
}

Upvotes: 1

YaleCheung
YaleCheung

Reputation: 630

The ThreadProc() prototype is

DWORD WINAPI ThreadProc(
  _In_  LPVOID lpParameter
);

So you need to change the Timer() declaration like:

DWORD WINAPI Timer()

Upvotes: 0

Related Questions