определяемая приложением функция, которая должна выполняться CreateThread
, должна иметь подпись:
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
);
, если мы использовали функцию члена класса (нестатическую) - она должна иметьподпись
class testt {
ULONG WINAPI testf();
};
необходимо помнить, что каждая нестатическая функция-член получает указатель на этот в качестве первого параметра.просто мы не явно заявляем об этом.в результате ULONG WINAPI testf(/*testt* this*/);
точно соответствует функция обратного вызова ThreadProc .и мы можем использовать его в качестве точки входа потока.
В этом проекте мне нужно использовать только Win32 API.
Я не понимаю, для чего нужно использовать обертки для бетонаэтот поток API, но код может выглядеть следующим образом:
template <class U>
class Thread
{
HANDLE _hThread;
DWORD _id;
public :
Thread() : _hThread(0) {}
~Thread()
{
if (_hThread) CloseHandle(_hThread);
}
ULONG Create(ULONG (WINAPI U::*member)(), U* This)
{
union {
LPTHREAD_START_ROUTINE lpStartAddress;
ULONG (WINAPI U::*_member)();
};
_member = member;
if (_hThread = CreateThread(0, 0, lpStartAddress, This, CREATE_SUSPENDED, &_id))
{
return NOERROR;
}
return GetLastError();
}
ULONG run()
{
return ResumeThread(_hThread) == MAXULONG ? GetLastError() : NOERROR;
}
ULONG wait()
{
return WaitForSingleObject(_hThread, INFINITE);
}
};
class testt {
PCWSTR _txt, _caption;
public :
testt(PCWSTR txt, PCWSTR caption) : _txt(txt), _caption(caption) { }
ULONG WINAPI testf() {
return MessageBox(0, _txt, _caption, 0);
}
void doIt() {
Thread<testt> t;
if (t.Create(&testt::testf, this) == NOERROR)
{
if (t.run() == NOERROR)
{
t.wait();
}
}
}
};
void demo()
{
testt o(L"text", L"caption");
o.doIt();
}
однако для сравнения кода без класса шаблона, но прямой запуск потока к функции-члену класса:
class testt {
PCWSTR _txt, _caption;
public :
testt(PCWSTR txt, PCWSTR caption) : _txt(txt), _caption(caption) { }
ULONG WINAPI testf() {
return MessageBox(0, _txt, _caption, 0);
}
void doIt() {
union {
LPTHREAD_START_ROUTINE lpStartAddress;
ULONG (WINAPI testt::*pfn)();
};
pfn = &testt::testf;
if (HANDLE hThread = CreateThread(0, 0, lpStartAddress, this, 0, 0))
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
}
};
void demo()
{
testt o(L"text", L"caption");
o.doIt();
}