Can you pass a method as a callback function 
Author Message
 Can you pass a method as a callback function

Is is possible to pass a member method as a call back function
to a routine that requires a call back function?

If not, what is the best way to do this?

I want to use SetWaitableTimer with a class and would like
to keep all the functionality encapsulated in my class.

Thanks



Tue, 28 Aug 2001 03:00:00 GMT  
 Can you pass a method as a callback function
    You can only pass a static member function address to a callback
function.  Regular member functions expect to have the hidden "This" pointer
passed to them, which the callback isn't going to do.  However, without the
"this" pointer, you have knowledge of your class, but not of the particular
object of that class.

    So, what do you do about that?  Well, if you are just going to need one
of these object, you can make every member variable static, which can be
accessed from a static member function.   But, this is probably going to
bite you later.

    I better method is to convince the callback to pass the this pointer to
your function.  For example:

class MyTimerBaseClass
{    public:

static VOID CALLBACK TimerProc( LPVOID lpArgToCompletionRoutine,
                DWORD dwTimerLowValue,  DWORD dwTimerHighValue)
    {
        MyTimerClass*    This =
reinterpret_cast<MyTimerClass*>lpArgToCompletionRoutine;

        This->RealTimerProc(dwTimerLowValue,  dwTimerHighValue);
    }

    virtual void RealTimerProc(DWORD dwTimerLowValue,  DWORD
dwTimerHighValue)
    {
             // do whatever -- you have full access to member variables here
            // This works best if you derive a new class from this base, and
implement
            // only this function in the derived class.
    }

    BOOL SetTimer(
          HANDLE hTimer,                          // handle to a timer
object
          const LARGE_INTEGER *pDueTime,          // when timer will become
signaled
          LONG lPeriod,                           // periodic timer interval
          BOOL fResume                            // flag for resume state);
    {
            return ::SetWaitableTimer(hTimer, pDueTime,  lPeriod,
                        MyTimerBaseClass::TimerProc,
                        (LPVOID) this,
                        fResume);
    };

Quote:
};

class MyTimerClass:: public MyTimerBaseClass
{
    public:
    virtual void RealTimerProc(DWORD dwTimerLowValue,  DWORD
dwTimerHighValue)
    {
             // do whatever -- you have full access to member variables here
    }

Quote:
};

    then

        MyTimerClass    timer;

        timer.SetTimer(hTimer,  &DueTime,  lPeriod, fResume);

The SetTimer member function will take care of the other parameters.

--
Truth,
   James [MVP]
http://www.NJTheater.Com       -and-
http://www.NJTheater.Com/JamesCurran

Quote:

>Is is possible to pass a member method as a call back function
>to a routine that requires a call back function?

>If not, what is the best way to do this?

>I want to use SetWaitableTimer with a class and would like
>to keep all the functionality encapsulated in my class.

>Thanks



Tue, 28 Aug 2001 03:00:00 GMT  
 Can you pass a method as a callback function
Dave -

Quote:
> Is is possible to pass a member method as a call back function
> to a routine that requires a call back function?

> If not, what is the best way to do this?

It isn't general possible.  The problem is that non-static member
functions take a hidden parameter (the 'this' value) that most callbacks
aren't expecting to provide.  For cases like yours, the callback
function will be bringing a void "user data" pointer.  What I do in
these cases is to give my class a static member function with the
signature of the callback.  I then use the 'this' pointer of my object
of interest as my user data.  The static member simply casts the
incoming void pointer to the correct class pointer and calls a method
for the object.  For example,

class CTimerHandler : public CObject
{
public:
   CTimerHandler(...);

   void OnTimer( DWORD dwTimerLowValue,
                 DWORD dwTimerHighValue );

protected:
   void CALLBACK TimerAPCProc(  LPVOID lpArgToCompletionRoutine   //
data value
                                DWORD dwTimerLowValue             //
timer low value
                                DWORD dwTimerHighValue            //
timer high value
                             );

Quote:
};

void CALLBACK CTimerHandler::TimerAPCProc(
   LPVOID lpArgToCompletionRoutine   // data value
   DWORD dwTimerLowValue             // timer low value
   DWORD dwTimerHighValue            // timer high value
)
{
   CTimerHandler* handler = (CTimerHandler*)lpArgToCompletionRoutine;
   ASSERT_VALID( handler );
   handler->OnTimer( dwTimerLowValue, dwTimerHighValue );

Quote:
}

CTimerHandler::CTimerHandler(...)
{
   BOOL SetWaitableTimer( hTimer, pDueTime, lPeriod,
     TimerAPCProc, this, fResume );

Quote:
}

In cases where there isn't a "user data" argument to the callback
function, you may be out of luck.

Hope this helps.

   David
================================
The opinions expressed are personal and may not
reflect UPS opinions.  No animals were hurt in
testing these opinions.



Tue, 28 Aug 2001 03:00:00 GMT  
 Can you pass a method as a callback function
[snip]
Quote:
>     [A] better method is to convince the callback to pass the this pointer to
> your function.  For example:

[snip]

The only thing about your method is that it places restrictions
on the form of the argument list for the callback.

I've struggled with this off and on for a while.  I'd really like
to be able to have a way that I could pass a regular-old function
pointer, a pointer to astatic member function, or some kind of pointer
to a class instance, and have a library routine not care which was
which. I struggled with trying to use operator(), but never quite got
it to do what I wanted.  A pointer to an instance, even an
instance with operator() overloaded correctly, can't stand in
totally transparently for a function pointer, at least, not
that I was able to do.

Is there any way to do this?



Wed, 29 Aug 2001 03:00:00 GMT  
 Can you pass a method as a callback function

Quote:


> >     [A] better method is to convince the callback to pass the this
pointer to
> > your function.  For example:

> The only thing about your method is that it places restrictions
> on the form of the argument list for the callback.

    I'm not sure I follow you about this.   The argument list of the
callback is defined by the (external) function doing the calling back.  I'm
just working within those limits.

Quote:
> I've struggled with this off and on for a while.  I'd really like
> to be able to have a way that I could pass a regular-old function
> pointer, a pointer to astatic member function, or some kind of pointer
> to a class instance, and have a library routine not care which was
> which. I struggled with trying to use operator(), but never quite got
> it to do what I wanted.  A pointer to an instance, even an
> instance with operator() overloaded correctly, can't stand in
> totally transparently for a function pointer, at least, not
> that I was able to do.

    It depends... Are you defining the callback parameters, or are you
working within someone else's?   If you control the calling function, then
you have quite a bit a leeway. (Although to get the object with a operator()
working, it will require that the caller by a template.


Thu, 30 Aug 2001 03:00:00 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Passing "callback" function to a function

2. Passing C++ Class Member Function to as a C Callback Function Parameter

3. Getting a pointer to object's methods from timer callback function

4. how do I use a calss method for a C style callback function

5. CALLBACK function as a method of class?

6. Callback function as class method?

7. Why I can't pass to WNDCLASS callback function but can if it static

8. Passing a pointer to a callback function

9. Passing something to callback function

10. passing derived-CDialog object member function as callback?

11. Passing user-defined interger value into Callback function ?

12. CALLBACK, CALLBACK, CALLBACK?

 

 
Powered by phpBB® Forum Software