running class method as a thread proc

  • Thread starter Thread starter Abubakar
  • Start date Start date
A

Abubakar

Hi,
Lets say I have a method called "listen_proc" inside "class1". There is
another method called "start" in the same class that has to start the
"listen_proc" inside a new thread. I am using CreateThread but I cannot
manage to pass the right function pointer, the compiler keeps on giving
error that it cant convert my given function to LPTHREAD_START_ROUTINE while
I try to cast it. In a simple c++ non-class file I can easily do it but this
class method prototype mismatch is causing this problem. Can someone plz
write a little example that has a method inside a class that is started in a
seperate thread using CreateThread.

Thanks,

-Ab.
 
Abubakar said:
Hi,
Lets say I have a method called "listen_proc" inside "class1". There
is another method called "start" in the same class that has to start
the "listen_proc" inside a new thread. I am using CreateThread but I
cannot manage to pass the right function pointer, the compiler keeps
on giving error that it cant convert my given function to
LPTHREAD_START_ROUTINE while I try to cast it. In a simple c++
non-class file I can easily do it but this class method prototype
mismatch is causing this problem. Can someone plz write a little
example that has a method inside a class that is started in a
seperate thread using CreateThread.

The problem is that you cannot convert a pointer to non-static member
function into an ordinary pointer to function, which is what CreateThread
wants.

The canonical solution is to write a static "trampoline" function that in
turn calls your non-static function:

class Active
{
private:
HANDLE m_hTthread;
static DWORD WINAPI ThreadStart(LPVOID info)
{
return static_cast<Active*>(info)->Run();
}

DWORD Run()
{
// your thread proc here
}

public:
Active()
m_hThread(INVALID_HANDLE_VALUE)
{
}

~Active()
{
// take appropriate steps to destroy/wait for your thread to
terminate
}

void Start()
{
m_hThread = CreateThread(
NULL,0,&Active::ThreadStart,this,0,NULL
);
}
};

Note that 'this' is passed to the 'lpParameter" parameter of CreateThread,
allowing the trampoline function to recover the this pointer and call your
non-static thread proc.

Note also that if you're linking to the static CRT, you should use
_beginthread or _beginthreadex instead of CreateThread. If you're linking
to the DLL verison of the CRT then it doens't matter which you use.

-cd
 
Thanks, that worked!

Ab.

Carl Daniel said:
The problem is that you cannot convert a pointer to non-static member
function into an ordinary pointer to function, which is what CreateThread
wants.

The canonical solution is to write a static "trampoline" function that in
turn calls your non-static function:

class Active
{
private:
HANDLE m_hTthread;
static DWORD WINAPI ThreadStart(LPVOID info)
{
return static_cast<Active*>(info)->Run();
}

DWORD Run()
{
// your thread proc here
}

public:
Active()
m_hThread(INVALID_HANDLE_VALUE)
{
}

~Active()
{
// take appropriate steps to destroy/wait for your thread to
terminate
}

void Start()
{
m_hThread = CreateThread(
NULL,0,&Active::ThreadStart,this,0,NULL
);
}
};

Note that 'this' is passed to the 'lpParameter" parameter of CreateThread,
allowing the trampoline function to recover the this pointer and call your
non-static thread proc.

Note also that if you're linking to the static CRT, you should use
_beginthread or _beginthreadex instead of CreateThread. If you're linking
to the DLL verison of the CRT then it doens't matter which you use.

-cd
 
Back
Top