(?) Класс + Многопоточность

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Lev
Сообщения: 45
Зарегистрирован: 14 фев 2005, 11:17

Привет всем.

У меня проблема, о ней ниже.
Цель:
Необходимо создать класс, который при своей инициализации (с помощью
коструктора) создавал бы поток, который в свою очередь мог бы иметь доступ к
члена класса, в котором он создан.

Код(упрощенный) такой:

class Ms
{

public:
Ms();
HANDLE heExit;
unsigned int WINAPI Rt(PVOID pvParam);

private:
HANDLE htRt;

};

Ms::Ms()
{
unsigned threadID;
heExit = CreateEvent(NULL, TRUE, FALSE, NULL);

htRt = (HANDLE)_beginthreadex( NULL, 0, &Rt, NULL, 0, &threadID ); // (?)
}

Проблема:
Компилятор ругается error C2276: '&' : illegal operation on bound member
function expression.

но если поставить в определении класса вместо unsigned int WINAPI Rt(PVOID
pvParam); поставить static unsigned int WINAPI Rt(PVOID pvParam); то
_beginthreadex спокойно это переваривает. Но мне не нужна статическая
функция - она не может получить доступ к нестатическим членам класса.

Спасибо.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Надо просунуть указатель this через параметр callback - функции.

htRt = (HANDLE)_beginthreadex( NULL, 0, &threadFunc, this, 0, &threadID );

//.....

static unsigned int __stdcall threadFunc(void* pvParam) {
Ms *this__ = static_cast<Ms *>(pvParam);
return this__->Rt();
}
2B OR NOT(2B) = FF
Lev
Сообщения: 45
Зарегистрирован: 14 фев 2005, 11:17

Непомогает, пишет всё тоже:
error C2276: '&' : illegal operation on bound member function expression
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Непомогает, пишет всё тоже:
А ты threadFunc статической сделал?
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Наверное ты забыл вместо Rt в вызове _beginthreadex, написать threadFunc. Других причин столь странного поведения не вижу.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Посмотри, как я делал:

Код: Выделить всё

#include "MyDlgClass.h"

// Эта функция выполняется в отдельном потоке...
unsigned __stdcall DlgConfigFunc(void *v)
{
	if (!v) return 0;

	((CMyDlgClass*)v)->UpdateDlgConfig();
	return 1;
}

// Обработчик какого-то события в окне диалога...
LRESULT CMyDlgClass::OnDlgEventResponse(<список аргументов>)
{
	_beginthreadex(NULL, 0, DlgConfigFunc, this, 0, NULL);
	return 0;
}

void CMyDlgClass::UpdateDlgConfig()
{
	// Какой-то код...
}

Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Вообще-то говоря желательно пользоваться имеющимися тредами вместо порождения новых:

unsigned __stdcall DlgConfigFunc(void *v)
{
do {
if(WaitForSingleObject(hEvent, INFINITE) != WAIT_OBJECT_0 || endFlag) { break; }
((CMyDlgClass*)v)->UpdateDlgConfig();
} while (1);
return 0;
}

LRESULT CMyDlgClass::OnDlgEventResponse(<список аргументов>)
{
SetEvent(hEvent);
return 0;
}
2B OR NOT(2B) = FF
Lev
Сообщения: 45
Зарегистрирован: 14 фев 2005, 11:17

#include "MyDlgClass.h"

// Эта функция выполняется в отдельном потоке...
unsigned __stdcall DlgConfigFunc(void *v)
{
if (!v) return 0;

((CMyDlgClass*)v)->UpdateDlgConfig();
return 1;
}

// Обработчик какого-то события в окне диалога...
LRESULT CMyDlgClass::OnDlgEventResponse(<список аргументов>)
{
_beginthreadex(NULL, 0, DlgConfigFunc, this, 0, NULL);
return 0;
}

void CMyDlgClass::UpdateDlgConfig()
{
// Какой-то код...
}
Спасибо. Этот прием мне помог. С помощью него можно решить задачу мою.
Но хотелось бы всетаки запускать функцию-член класса что бы было поменьше глобальных функций.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Но хотелось бы всетаки запускать функцию-член класса что бы было поменьше глобальных функций.
Нестатический метод класса НЕ МОЖЕТ быть функцией потока: у них разные сигнатуры, и что хуже, соглашения по вызову.
Lev
Сообщения: 45
Зарегистрирован: 14 фев 2005, 11:17

Спасибо всем, помогли. Вопросов больше пока не имею.
Ответить