Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

Функция потока - член класса, чего сдлеать, чтобы исправить указатель на неё?

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
Ilya
Гость





СообщениеДобавлено: Ср Мар 05 2003 22:51    Заголовок сообщения: Функция потока - член класса, чего сдлеать, чтобы исправить указатель на неё? Ответить с цитатой

Мне нужно, чтобы конструктор объекта создавал новый поток. При этом, функция потока также должна быть методом этого объекта. Казалось бы - нормальные требования. Но у меня возникает проблема, которую я не знаю как решить. Проблема заключается в следующем: третий аргумент функции __beginthreadex имеет тип void(__stdcall*) (void*), но если функция потока определена как метод класса, то указатель на неё будет иметь вид void(__stdcall Bug:: *) (void *).
Расскажите пожалуйста как проблему решить (красиво)???
Я пытался сделать функцию потока friend'ом, чтобы "вытащить" её в глобальную область видимости, но она, естественно использует переменные и другие методы класса, при попытке вызвать функцию-метод с помощью Bug::Chase() (например) происходит следующая ругань: 'Bug::Chase' : illegal call of non-static member function. See declaration of 'Chase'

Дело в том, что я совсем новичок и разобраться самому очень тяжело.
Поможите, чем можите! Буду благодарен.
Вернуться к началу
chaka
Гость





СообщениеДобавлено: Пт Мар 07 2003 14:30    Заголовок сообщения: Re: Функция потока - член класса, чего сдлеать, чтобы исправить указатель на неё? Ответить с цитатой

Дело в том, что при вызове функции-члена в стек первым параметром неявно помещается указатель на экземпляр класса (this). Так что использование функции члена и обычной глобальной функции хоть и семантически идентичны, но все же различаются. Система при создании потока требует именно адрес глобальной точки входа, она ничего не знает о this и т.д., по этому возникают некоторые неудобства при использовании объектно-ориентированных способов программирования в "несовсем" объектно-ориентированной системе. Как правило решение выглядит следующим образом.
1. Создается интерфейсный класс, который определяет точку входа, которыю будет использовать система при создании нити и декларируется рабочаяя функция, которая будет выполнять необходимые действия, но уже в контексте заданного класса.
2. Нужный нам класс наследует от этого абстрактного интерфейсного класса.
3. Создается поток и в качестве указателя на точку входа передается метод интерфейсного класса.

Итак
1:
//entry.hpp
#include // EXIT_SUCCESS, EXIT_FAILURE
#include
class IEntry{
public:
virtual unsigned int work_func() = 0; //перегружаем в производном классе для выполнения полезной работы
static unsigned int __stdcall entry(void* pv){ //static - чтобы убрать this
IEntry* p = reinterpret_cast(pv);
unsigned int dwRes = 0;
try{
dwRes = p->work_func();
}
catch(...){
assert(0);
dwRes = EXIT_FAILURE;
}
return dwRes;
}
};
2:
//worker.hpp
#include "entry.hpp"
class CWorker : public IEntry{
public:
virtual unsigned int work_func(); //рабочая функция
};
//worker.cpp
#include "worker.hpp"
#include // cout
#include // endl
using namespace std;
unsigned int CWorker::work_func(){
cout
#include
void f(){
CWorker w;
unsigned int dwThreadId;
HANDLE h = (HANDLE)_beginthreadex(0, 0, IEntry::entry, static_cast(&w), 0, &dwThreadId);
Sleep(10000); //чтобы успела отбаротать вновь созданная нить
}
int main(int /*argc*/, char** /*argv*/){
f();
return EXIT_SUCCESS;
}
P.S. Вот, как бы, и все, единственно - форма для ввода ответов не очень располагает для написания исходных кодов, так что если все, что я здесь написал будет одним сплошным куском текста, а не отформатированным листингом, то заранее извиняюсь. Ну, а если где есть описки, так это с кем не бывает Smile
Вернуться к началу
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...