URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 1432
[ Назад ]

Исходное сообщение
"указатель на метод-член класс и инициализация таймера"

Отправлено vvk , 25-Фев-03 22:16 
вот такая фигня. боюсь, что не разрешимая и прийдется выкручиваться по другому. но мало ли что, вдруг кто что подскажет. есть инициализация таймера такая:

struct itimerval tv;
struct sigaction action;
sigemptyset(&action.sa_mask);
action.sa_handler = (void(*)(int))ontimer;  // ВОТ ТУТ ПРОБЛЕМА!
action.sa_flags = SA_RESTART;
sigaction(SIGALRM,&action,0);
    
tv.it_interval.tv_sec = interval;
tv.it_interval.tv_usec = 0;
tv.it_value.tv_sec = 1; // sends first signal after one second
tv.it_value.tv_usec = 0;
setitimer (ITIMER_REAL, &tv, 0);

пока все это было просто 'c' и ontimer было просто функцией, все было чудно. но после рефакторинга вынес все это в отдельный класс. в результате ontimer стала членом.
чтобы получить указатель на функцию член, я должен теперь писать так:

action.sa_handler = (void(*)(int))&MyClass::ontimer;

Но!!! нифига!!! он говорит не могу сконвертить void (MyClass::*) int to void (*) int

Есть варианты, или безнадежно?


Содержание

Сообщения в этом обсуждении
"RE: указатель на метод-член класс и инициализация таймера"
Отправлено sas , 26-Фев-03 08:32 
>вот такая фигня. боюсь, что не разрешимая и прийдется выкручиваться по другому.
>но мало ли что, вдруг кто что подскажет. есть инициализация таймера
>такая:
>
>struct itimerval tv;
>struct sigaction action;
>sigemptyset(&action.sa_mask);
>action.sa_handler = (void(*)(int))ontimer;  // ВОТ ТУТ ПРОБЛЕМА!
>action.sa_flags = SA_RESTART;
>sigaction(SIGALRM,&action,0);
>
>tv.it_interval.tv_sec = interval;
>tv.it_interval.tv_usec = 0;
>tv.it_value.tv_sec = 1; // sends first signal after one second
>tv.it_value.tv_usec = 0;
>setitimer (ITIMER_REAL, &tv, 0);
>
>пока все это было просто 'c' и ontimer было просто функцией, все
>было чудно. но после рефакторинга вынес все это в отдельный класс.
>в результате ontimer стала членом.
>чтобы получить указатель на функцию член, я должен теперь писать так:
>
>action.sa_handler = (void(*)(int))&MyClass::ontimer;
>
>Но!!! нифига!!! он говорит не могу сконвертить void (MyClass::*) int to void
>(*) int
>
>Есть варианты, или безнадежно?

Как минимум 3 (может быть и еще вариации) Рассмотрим пример (не уверен что он скомпилируется без ошибок, т.к. не проверял)

#include <iostream>

using namespace std;

static const void* g_C_PTR;

class C {

public:
    C() {}

    // Статические функции члены не используют указатель this
    // И на самом деле они такие-же как и обыкновенные С ф-ции
    // (signature, name, arguments, their order etc.)
    static void static_f( int i ) { cout << "void C::static_f( int ): " << i << endl; }

    // Oбычная функция член
    void f( int i ) const
    {
        cout << "void C::f( int ): " << i << endl;
    }

    // Статическая функция оболочка для вызова f
    static void f_wrapper( const void* c_ptr, int i )
    {
        const C* ptr = static_cast<const C*>( c_ptr );
        ptr->f( i );
    }

    // Вариация предидущей ф-ции в том случае если библотека чужая
       // и нельзя сделать как в f_wrapper указатель на объект класса
    //
    // Да глобальные переменные - это плохо, но мы объявляем
    // static const void* g_C_PTR;   (C - означает наш класс)
    static void f_global_var_wrapper( int i )
    {
        const C* ptr = static_cast<const C*>( g_C_PTR );
        ptr->f( i );
    }
    
};

typedef void (*FPTR)(int);
typedef void (*F_VP_PTR)(const void*,int);

int main()
{
    C c;
    const C* c_ptr = const_cast<const C*>( &c );

    FPTR fptr;
    F_VP_PTR f_vp_ptr;

    // or fptr = static_cast<FPTR>( &C::static_f );
    fptr = &C::static_f;
    (*fptr)( 123 );

    f_vp_ptr = &C::f_wrapper;
    (*f_vp_ptr)( static_cast<const void*>( c_ptr ), 321 );

    g_C_PTR = static_cast<const void*>( c_ptr );
    fptr = &C::f_global_var_wrapper;
    fptr( 555 );

    return 0;
}

Успехов
--- sas

PS безнадежных ситуаций нет :))


"RE: указатель на метод-член класс и инициализация таймера"
Отправлено vvk , 26-Фев-03 10:01 
ок. спасибо

на данный момент выкрутился созданием статической функции, которая цепляется на таймер и делает дело так

static void ontimer(int) {
  MyClass mc;
  mc.change_timer_property();
}

вот. т.е. в этом случае он находит мое окно и изменяет его Atom соответствующий, а это событие я ловлю в цикле сообщений.