0

嗨,我一直在尝试使用 posix 计时器库来实现计时器,但我在实现中犯了一个错误,我使用了来自网络的示例并尝试将其封装在一个类中,但是编译器不喜欢它,基本上是在尝试分配回调函数 intsigev.sigev_notify_function = TIMER0_IRQHandler;但我无法得到任何结果。代码如下:

类定义:

#include <sys/time.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
//se agrego para eliminar el siguiente warning del compilador
//warning: incompatible implicit declaration of built-in function 'memset'
#include <string.h> /* memset */
#include <unistd.h> /* close */


#define TIMEVAL_MAX 0xFFFFFFFF
#define TIMEVAL unsigned int
// The timer is incrementing every 4 us.
//#define MS_TO_TIMEVAL(ms) (ms * 250)
//#define US_TO_TIMEVAL(us) (us>>2)

// The timer is incrementing every 8 us.
#define MS_TO_TIMEVAL(ms) ((ms) * 125)
#define US_TO_TIMEVAL(us) ((us)>>3)

class Timer
{
public:
    Timer();
    void initTimer();
    void setTimer(TIMEVAL aValue);
    TIMEVAL getElapsedTime( void ) ;
    void TIMER0_IRQHandler(sigval_t val);
private:
    struct timeval last_sig;
    timer_t timer;

};

以及与编译器冲突的函数:

void Timer::initTimer()
{
        struct sigevent sigev;

        // Take first absolute time ref.
        if(gettimeofday(&last_sig,NULL)){
            perror("gettimeofday()");
        }

        memset (&sigev, 0, sizeof (struct sigevent));
        sigev.sigev_value.sival_int = 0;
        sigev.sigev_notify = SIGEV_THREAD;
        sigev.sigev_notify_attributes = NULL;
        sigev.sigev_notify_function = &TIMER0_IRQHandler;

        if( timer_create (CLOCK_REALTIME, &sigev, &timer)) {
            perror("timer_create()");
        }

}
*//callback function
void Timer::TIMER0_IRQHandler(sigval_t val)
{
    if(gettimeofday(&last_sig,NULL)) {
        perror("gettimeofday()");
    }
    printf("TIMER NOTIFY\n");
}

提前谢谢!

4

2 回答 2

2

要调用成员函数,您还需要指向 的指针this,这意味着您不能直接执行此操作。但是,您可以使用静态函数作为回调的包装器,它可以提取this指针并调用您的真实回调:

class Timer
{
public:
    static void handler_wrapper(sigval_t val);
    void handler();
};

void Timer::handler_wrapper(sigval_t val)
{
    Timer *object = (Timer *)val.sival_ptr;
    object->handler();
}

void Timer::handler(void)
{
    // do whatever.  just remember what thread context you're in
}

// in main
sigev.sigev_value.sival_ptr = (void*) this;
sigev.sigev_notify_function = &Timer::handler_wrapper;
于 2013-08-07T18:12:21.360 回答
0

您可以使用std::bind创建函数对象来传递要在计时器(或超时)结束时调用的非静态成员函数。

std::bind(&class_name::mem_func, obj_ptr, args_list ...);

这样做的缺点类似于静态成员函数,即线程没有父对象的上下文,尽管您可能能够独立运行成员函数(如果它不使用任何父对象属性)。这与静态成员函数几乎相同,它要求类的成员属性是静态的,以防它们被它需要/访问/使用。

注意:在参数中传递对象引用(使用std::ref)或指针,并在您的成员函数中使用它。

于 2019-12-10T16:57:47.880 回答