Using function pointer in callback function

Discussion in 'C++' started by pvdm, Sep 9, 2003.

  1. pvdm

    pvdm Guest

    Hi,



    I am writing an app which encapsulates a multimedia timer. I implemented
    a TimerProc as static member function and a static member variable pThis
    as pseudo this variable to access in the static TimerProc function.
    timeSetEvent uses TimerProc to set the callback function.



    m_pCallback is a function that is passed using the
    SetTimerCallbackFunction. It's a function that an object owning the
    CMMTimer object can pass to the CMMTimer class. What I want is that
    every time the TimerProc function is called, the m_pCallback function is
    executed, resulting in the object owning the timer processing the timer.



    Header file looks like this:



    /***************************************/

    typedef void (CALLBACK * MMTIMERCALLBACK) (TRIGGER eTrigger, UINT uID,
    int iVal);

    CMMTimer

    {

    public:

    BOOL Stop();

    BOOL Start(UINT uPeriod);

    BOOL Initialize(UINT uResolution);

    CMMTimer();

    virtual ~CMMTimer();

    void SetTimerCallbackFunction(MMTIMERCALLBACK pCallback);



    private:

    MMTIMERCALLBACK m_pCallback;

    UINT m_uResolution;

    UINT m_uPeriod;

    UINT m_uTimerID;

    BOOL m_bInitialized;



    static CMMTimer *pThis;

    static void CALLBACK TimerProc(UINT wTimerID, UINT msg, DWORD dwUser,
    DWORD dw1, DWORD dw2);

    }



    /***************************************/



    Parts of cpp file look like this



    /***************************************/



    CMMTimer* CMMTimer::pThis = NULL;



    void CMMTimer::SetTimerCallbackFunction(MMTIMERCALLBACK pCallback)

    {

    m_pCallback = pCallback;

    }



    BOOL CMMTimer::Start(UINT uPeriod)

    {

    if (!m_bInitialized) return FALSE;

    m_uPeriod = uPeriod;

    pThis = this;

    m_uTimerID =

    timeSetEvent(

    m_uPeriod,

    m_uResolution,

    TimerProc,

    (DWORD) this,

    TIME_PERIODIC );

    if(! m_uTimerID)

    return FALSE;

    else

    return TRUE;

    }



    void CALLBACK TimerProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD
    dw1, DWORD dw2)

    {

    // I tried this

    CMMTimer * pseudoThis = (CMMTimer *) dwUser;

    pseudoThis->m_pCallback(<TIMERT, 0, 0); #error#

    // and this

    pThis->m_pCallback(<TIMERT, 0, 0); #error#

    }



    I also tried helper functions.





    The problem is that this code compiles perfectly, but when I execute the
    code, the debugger shows problems at the lines #error#. m_pCallback
    cannot be called, the pointer points at memory address 0xcccccccccccccc



    I really would like this problem solved.



    Thank you



    pvdm





    }


    --
    Posted via http://dbforums.com
     
    pvdm, Sep 9, 2003
    #1
    1. Advertising

  2. pvdm

    tom_usenet Guest

    On Tue, 09 Sep 2003 05:02:58 -0400, pvdm <>
    wrote:

    >
    >Hi,
    >
    >I am writing an app which encapsulates a multimedia timer. I implemented
    >a TimerProc as static member function and a static member variable pThis
    >as pseudo this variable to access in the static TimerProc function.


    Why do you need pThis? You are passing the this argument to the
    callback anyway.

    >timeSetEvent uses TimerProc to set the callback function.


    >m_pCallback is a function that is passed using the
    >SetTimerCallbackFunction. It's a function that an object owning the
    >CMMTimer object can pass to the CMMTimer class. What I want is that
    >every time the TimerProc function is called, the m_pCallback function is
    >executed, resulting in the object owning the timer processing the timer.


    Right, sounds reasonable.

    >Header file looks like this:
    >
    >typedef void (CALLBACK * MMTIMERCALLBACK) (TRIGGER eTrigger, UINT uID,
    >int iVal);
    >
    >CMMTimer


    class CMMTimer?

    >
    >{
    >
    >public:
    >
    > BOOL Stop();
    >
    > BOOL Start(UINT uPeriod);
    >
    > BOOL Initialize(UINT uResolution);
    >
    > CMMTimer();
    >
    > virtual ~CMMTimer();
    >
    > void SetTimerCallbackFunction(MMTIMERCALLBACK pCallback);
    >
    >
    >
    >private:
    >
    > MMTIMERCALLBACK m_pCallback;
    >
    > UINT m_uResolution;
    >
    > UINT m_uPeriod;
    >
    > UINT m_uTimerID;
    >
    > BOOL m_bInitialized;
    >
    > static CMMTimer *pThis;


    I don't see any use of pThis. Remove it.

    >
    > static void CALLBACK TimerProc(UINT wTimerID, UINT msg, DWORD dwUser,
    > DWORD dw1, DWORD dw2);
    >
    >}
    >CMMTimer* CMMTimer::pThis = NULL;


    Again, scrub this.

    >void CMMTimer::SetTimerCallbackFunction(MMTIMERCALLBACK pCallback)
    >
    >{
    >
    > m_pCallback = pCallback;
    >
    >}
    >
    >
    >
    >BOOL CMMTimer::Start(UINT uPeriod)
    >{
    > if (!m_bInitialized) return FALSE;
    > m_uPeriod = uPeriod;
    > pThis = this;


    What if you have more than one timer at a time?

    In any case, you need to check the callback here:

    if (!m_pCallback)
    {
    return FALSE;
    }

    and make sure m_pCallback is initialized to NULL by your constructor.

    > m_uTimerID =
    > timeSetEvent(
    > m_uPeriod,
    > m_uResolution,
    > TimerProc,
    > (DWORD) this,
    > TIME_PERIODIC );
    > if(! m_uTimerID)
    > return FALSE;
    > else
    > return TRUE;
    >}


    That looks ok.

    >void CALLBACK TimerProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD
    >dw1, DWORD dw2)
    >
    >{
    >
    >// I tried this
    >
    > CMMTimer * pseudoThis = (CMMTimer *) dwUser;
    >
    > pseudoThis->m_pCallback(<TIMERT, 0, 0); #error#


    That looks correct, apart from "<TIMERT" which isn't valid C++.

    >// and this
    >
    > pThis->m_pCallback(<TIMERT, 0, 0); #error#


    No need for this. Where is pThis initialized, anyway?

    >}
    >
    >I also tried helper functions.


    How so?

    >The problem is that this code compiles perfectly, but when I execute the
    >code, the debugger shows problems at the lines #error#. m_pCallback
    >cannot be called, the pointer points at memory address 0xcccccccccccccc


    That suggests that m_pCallback hasn't been initialized. Perhaps you
    are calling SetTimerCallbackFunction on a different instance of your
    timer class to the one you call Start on.

    >I really would like this problem solved.


    The code you've posted looks generally ok. It must be the code using
    your timer class that is at fault. However, drop the static member
    variable, and add the test to Start, and you'll probably find your
    problem.

    Tom
     
    tom_usenet, Sep 9, 2003
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    10
    Views:
    704
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    844
    Jordan Abel
    Mar 28, 2006
  3. Ramesh
    Replies:
    11
    Views:
    4,215
    James Kanze
    Dec 27, 2008
  4. Dat Chu
    Replies:
    8
    Views:
    2,647
    MarkyMark101
    Aug 28, 2009
  5. Replies:
    4
    Views:
    1,268
    Fred Zwarts
    Jul 2, 2009
Loading...

Share This Page