Callbacks and events

D

Dave Boland

I read a lot of discussion about callback functions as used in C (as in
qsort for example). I'm comfortable with this as it is really a
function pointer. What I'm not totally clear about is how (or if) a
callback differs from an event such as GUI's use. One of the things I
found about events, at least in a VB6 project I did, is that an event
can be broadcast to all objects and they can use it if desired (code
only and GUI objects). Each object has to have a receive function for
that event though.

The only way I can see to do event broadcasting with a callback is to
have a special callback that in turn calls a list of receiver functions
that would be in each module. For example, a timer that broadcasts a
time tick every second would call a function (for example)
Timer_1min(void) that in turn would call functions in all of the modules
that need to know the time. I've also thought about a message que, but
that is begining to sound like too musch work. Is there a better way?

Thanks for any helpful information.

Dave,
 
E

Eric Sosman

Dave said:
I read a lot of discussion about callback functions as used in C (as in
qsort for example). I'm comfortable with this as it is really a
function pointer. What I'm not totally clear about is how (or if) a
callback differs from an event such as GUI's use. One of the things I
found about events, at least in a VB6 project I did, is that an event
can be broadcast to all objects and they can use it if desired (code
only and GUI objects). Each object has to have a receive function for
that event though.

The only way I can see to do event broadcasting with a callback is to
have a special callback that in turn calls a list of receiver functions
that would be in each module. For example, a timer that broadcasts a
time tick every second would call a function (for example)
Timer_1min(void) that in turn would call functions in all of the modules
that need to know the time. I've also thought about a message que, but
that is begining to sound like too musch work. Is there a better way?

A "callback function" is simply a function. Some piece
of code calls it, it executes, and it returns to the caller.
No mysteries, nothing special about it.

When we say that one function is a callback and another
isn't, we're really not talking about the functions but about
how they happen to get called. When we write a call to an
"ordinary" function we know as we're typing in the code just
which function we want to call, and we write it's name: printf()
or sqrt() or whatever. When we write a call to a callback
function, though, we generally don't know what function we're
calling. Not only that, but we're probably not going to write
the called function ourselves -- or at any rate there's usually
some way for a third party to write a brand-new function and
get our code to "call back" to it. The set of possible functions
that might be called back is open-ended and usually extensible.

It's a mechanism for postponing the decision about what
function to call. Instead of making that decision when you
write the code, you can make it at run-time and you can choose
a function that didn't even exist when the call was written.
This ability to postpone the choice gives great flexibility,
and allows you to use a "plug-in" style to extend the capabilities
of a piece of code.

What are the required mechanisms? First, you need a way
to write a call to a function whose name isn't known -- in C,
the function pointer provides this capability; other languages
use other mechanisms. Second, you need some kind of protocol
that allows somebody to set your function pointer to point at
the function he'd like you to "call back" to. This can be as
simple as just providing the pointer as an argument, as in
qsort(), or maybe there's a way to "register" the function,
as with atexit().

Your timer example would probably use a registration-style
protocol. There'd be a function that adds a function pointer
to the list of functions to be called at each tick, and perhaps
another function to remove and "de-register" the callback. Each
interested module would register its own callback as part of its
initialization (probably), and the code that detects timer ticks
would simply run down the list of pointers, calling each callback
in turn. Fancier schemes are, of course, possible.

Is there a better way? Maybe, maybe not: "Better" is in the
eye of the beholder, and a mechanism than blends in well with
one program may prove awkward in another.
 
J

Jack Klein

I read a lot of discussion about callback functions as used in C (as in
qsort for example). I'm comfortable with this as it is really a
function pointer. What I'm not totally clear about is how (or if) a
callback differs from an event such as GUI's use. One of the things I
found about events, at least in a VB6 project I did, is that an event
can be broadcast to all objects and they can use it if desired (code
only and GUI objects). Each object has to have a receive function for
that event though.

The only way I can see to do event broadcasting with a callback is to
have a special callback that in turn calls a list of receiver functions
that would be in each module. For example, a timer that broadcasts a
time tick every second would call a function (for example)
Timer_1min(void) that in turn would call functions in all of the modules
that need to know the time. I've also thought about a message que, but
that is begining to sound like too musch work. Is there a better way?

The better way, if you are serious, is to use message queues. No
other method scales as well. Similar approaches using things like bit
flags and such can work well for relatively small applications, but
hit a brick wall quickly as complexity increases.

And before anybody objects, it is quite possible to implement systems
based on message queues, or event flags, in standard C that have
nothing to do with multitasking, preemption, or threads.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top