Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > pthread_create(&p,NULL,run,func_pointer)


Автор: zaytsewa 9.4.2009, 14:18
хочется передать в функцию run в качестве параметра указатель на другую функцию (другого класса)

реально ли это сделать??

в ф-ции run func_pointer не воспринимается как указатель на функцию((

Код


template <class T>
Thread::Thread(string& (T::*user_func)()) {

    pthread_create(&fd,NULL,run,user_func); 
    fds[0].fd = fd;
    fds[0].events = POLLIN;
    nfds = 1;
}


void* Thread::run(void* user_func) 
{

    while (1)
    {
        poll(fds,nfds,-1);
        if (fds[0].revents == POLLIN) // данные на входе файлового дескриптора
            {
                user_func(); // запускаем ф-цию польз-ля
            }
    }
}

Автор: azesmcar 9.4.2009, 15:54
Цитата

реально ли это сделать??

да

Цитата

в ф-ции run func_pointer не воспринимается как указатель на функцию((

ну ясное дело smile это же указатель на void, откуда компилятору знать что ты туда указатель на функцию передаешь. Сделай cast.
дам пример, а там разберешся думаю
Код

#include <iostream>

typedef void *userfunc(void);

void foo()
{
    std::cout << "Hello world!" << std::endl;
}

void run(void* func)
{
    ((userfunc*)func)();
}

int main()
{
    run( foo );
}


zaytsewa
а вообще некоторые указатели на функции могут занимать больше памяти чем может содержать void*, так что лучше передавай указатель на указатель или заверни в структуру.


Автор: X-3R1 10.4.2009, 10:24
Я заметил: 
Код

pthread_create(&fd,NULL,run,user_func);

где run:
Код

void* Thread::run(void*);


Но ведь pthread_create ожидает функции void (*func)(void*), а не void (T::*func)(void*). Разве это скомпиллируется ? 
И ещё такой вопрос, как работать с сишными API которые ожидают указатель на функцию (signal, pthread_create etc) в ООП. Как-нибудь можно стандартными средствами языка C++ передать такой функции указатель на метод класса, а не указатель на статический метод или глобальную функцию ? Вроде бы знаю что boost::bind нечто подобное умеет.

Автор: MAKCim 10.4.2009, 10:38
Цитата(X-3R1 @  10.4.2009,  10:24 Найти цитируемый пост)
Как-нибудь можно стандартными средствами языка C++ передать такой функции указатель на метод класса, а не указатель на статический метод или глобальную функцию ?

нет

Автор: azesmcar 10.4.2009, 10:40
X-3R1
если функция статическая - сработает

Добавлено через 1 минуту и 4 секунды
X-3R1
можно сделать статическую и передавать ей this. А из нее вызывать соответствующую мембер функцию

Автор: X-3R1 10.4.2009, 11:39
Цитата(MAKCim @  10.4.2009,  08:38 Найти цитируемый пост)
нет 

можно =)))
Цитата(azesmcar @  10.4.2009,  08:40 Найти цитируемый пост)
можно сделать статическую и передавать ей this. А из нее вызывать соответствующую мембер функцию 

да ты прав =) Уже написал враппер:

Код

template <class T, void (T::*method)(void)>
void wrap_func(void* pObj)
{
    T *obj = static_cast<T *>(pObj);
    (obj->*method)();
}



Автор: azesmcar 10.4.2009, 11:46
X-3R1
Цитата

можно =)))

нет smile нельзя
то что я написал это обходное решение того что тебе нужно. А передать мембер функцию как ThreadProc - нельзя.

Автор: X-3R1 10.4.2009, 11:51
Цитата(azesmcar @  10.4.2009,  09:46 Найти цитируемый пост)
то что я написал это обходное решение того что тебе нужно. А передать мембер функцию как ThreadProc - нельзя. 

Это уже не важно, главное что теперь:
Код

pthread_create( ..., wrap_func<Thread, &Thread::run>, this );

работает. И wrap_func не обязательно делать глобальной функцией или статическим методом.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)