0

こんにちは、posix タイマー ライブラリを使用してタイマーを実装しようとしていますが、実装を間違えています。Web の例を使用して、クラスにカプセル化しようとしていましたが、コンパイラはそれを好まず、基本的にしようとしています。コールバック関数を int に割り当てますsigev.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");
}

事前にt​​hx!

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 に答える