A high-level routine
called from a low-level
Software systems are usually built in a hierarchical fashion: higher-level routines call lower-level routines, which perform services on their behalf. For example, an application program might invoke a GUI library or an XML library.
The normal way a library communicates with its caller is by return value. That is, function
f() calls library function
g() returns, various variables in
f() are set;
f() interprets these results, which
g() generated for it. Note that this method of communication requires the library routine to terminate to allow communication to take place.
But what if the library routine must communicate with the caller without returning? (Programmers from the 1970s use coroutines to do this kind of thing; it's not too different in practice) For instance, in a GUI application the event loop might be a library routine, but the application has to perform actions in response to GUI events. A program using an XML parser could be returned a parse tree of the input, but that wastes memory if the program isn't interested in most of the items, and it relegates to the program the generic task of correctly traversing the tree.
The solution is to employ callbacks. The library is instructed to call various routines on certain conditions. For instance, a GUI library might be told to call a certain routine when a certain slider is moved; an XML library might be told to pass a certain routine the contents of a document's
<TITLE> tag. Specifying a long list of such callbacks ties the library routine's generic functionality to the specific functionality the caller requires.
In C, callbacks are generally specified with function pointers to the application-level functions; these functions are called with parameters defined in the library API. A good callback API will always pass a parameter of type
void * pointing to "callback data"; this parameter is passed in from the application, and can be used to point to some application-specific data. C++ allows more exotic means of calling functions; callbacks are generally functors (or function objects), and don't require an extra typeless parameter passed from the library. Function languages and languages in the Lisp family have first-class functions with closures which can be utilised directly for callbacks.