template<class T, DWORD(T::*ClassFunc)()>
inline DWORD WINAPI thread_to_member_thunk(void* object)
{
return (reinterpret_cast<T*>(object)->*ClassFunc)();
}
template<class T>
void ThreadClass::Start(T *object, DWORD(T::*ClassFunction)())
{
CreateThread(0, 0, thread_to_member_thunk<T, this->*ClassFunction>, object, 0, 0);
};
и вызываем функцию:
m_Thread.Start(this, &MyClass::MainThreadFunction);
Исполнение функции-члена класса в потоке.
Есть академический интерес в создании небольшого набора классов-оберток вокруг апишных функций работы с потоками и объектам синхронизации. ATL хорошо, но громоздко.
Сейчас никак не соображу, как правильно написать код, позволяющий в качестве рабочей функции потока указать член-функцию класса. Делаю так:
Код:
Компилятор ругается:
Код:
error C2440: 'type cast' : cannot convert from 'DWORD (__stdcall *)(void *)' to 'LPTHREAD_START_ROUTINE'
Что я неправильно делаю, благородные доны?
Заранее благодарен.
У меня встречный вопрос, а чем не устраивает классическое решение со static-функцией и передачей ей указателя на "свой" объект? Ведь в сущности, ваш код сводится к тому же самому.
Цитата: Alexander92
У меня встречный вопрос, а чем не устраивает классическое решение со static-функцией и передачей ей указателя на "свой" объект? Ведь в сущности, ваш код сводится к тому же самому.
Там нет шаблонов.
Код:
class Test
{
public:
DWORD ThreadFunc(){return 0;};
template<class T>
void StartThread(T *object, DWORD(T::*ClassFunc)())
{
CreateThread(0, 0, ClassFunc, object, 0, 0);
}
};
class Test2
{
public:
// Test2()
// {
// CreateThread(0, 0, &Test2::ThreadFunc, this, 0, 0);
// }
static DWORD WINAPI ThreadFunc(LPVOID param)
{
Test2 *localObj = reinterpret_cast<Test2*>(param);
return localObj->ThreadFunc();
};
DWORD ThreadFunc()
{
return 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Test myThr;
Test2 myObj;
myThr.StartThread(&myObj, &Test2::ThreadFunc);
return 0;
}
{
public:
DWORD ThreadFunc(){return 0;};
template<class T>
void StartThread(T *object, DWORD(T::*ClassFunc)())
{
CreateThread(0, 0, ClassFunc, object, 0, 0);
}
};
class Test2
{
public:
// Test2()
// {
// CreateThread(0, 0, &Test2::ThreadFunc, this, 0, 0);
// }
static DWORD WINAPI ThreadFunc(LPVOID param)
{
Test2 *localObj = reinterpret_cast<Test2*>(param);
return localObj->ThreadFunc();
};
DWORD ThreadFunc()
{
return 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Test myThr;
Test2 myObj;
myThr.StartThread(&myObj, &Test2::ThreadFunc);
return 0;
}
Спокойно компилируется, если создавать поток в конструкторе Test2 (закоменченный код). Но мне хочется инкапсулировать все эти хэндлы в отдельном классе, потому пытаемся создать поток через класс Test. Получаем точно такую же ошибку.
Я, наверное, чего-то не понимаю?
PS: И вас не смущает конкурентное исполнение вашего нового потока и конструктора?
Цитата: Ramon
Изучите для разнообразия виртуальные члены класса.
PS: И вас не смущает конкурентное исполнение вашего нового потока и конструктора?
PS: И вас не смущает конкурентное исполнение вашего нового потока и конструктора?
Ни разу не понял Ваш ответ.
Пожалуйста, для заднего ряда, переформулируйте свою мысль доступнее.
Спасибо.