what's a callback?

Dec 19, 2004 118 Replies

Example. Take the Windows GDI LineDDA function. It takes 2 points as input and calculates all points that make a line between them. Now LineDDA calculates the first point, but it can't just return to the caller because the other points have to be calculated too. OTOH, it doesn't know what to do with the point (should it be drawn on a canvas, or added to a list?) That's why the calling routine has to supply a pointer to a callback function. Each time LineDDA has calculated a point it passes it to the callback function. The callback function may draw the point on a canvas, that's part of the application, and after it's done it returns control back to the LineDDA function, which then goes on to calculate the next point. So the application calls LineDDA, and during the LineDDA algorithm it calls back an application function. In the LineDDA case the callback will called several times, but it could also be just once.

Another example. Hans-Bernhard already mentioned sorting. Sorting can only be done within ordered set. Numerical lists are ordered differently from numerical lists, so you'll have different compare functions. Apart from the comparison itself however, the sorting algorithm can be the same for any type of set. So you write a sort routine requiring a callback function. The sorting routine knows when which item should be compared to which other. That's defined in the algorithm. But it doesn't know how thsi comparison is to be done. So it calls the callback, saying "hey, I've got an item A and an item B here which require comparison. Which should go first?". The callback function decides and returns the result to the sorting routine, which may e.g. decide that A and B should be swapped.

HTH

-- Steven

"Fred Bloggs" schreef in bericht news: snipped-for-privacy@nospam.com...

It is a simple concept. I think the word 'hook was more common with hardware interrupts or hardware related bios calls. Later, with graphical user interfaces, Apple Mac and GEM, these mechanisms were named callbacks. I guess, under that name they must be around for

20-25 years...
Thanks, Frank. (remove 'q' and 'invalid' when replying by email)

When you pass the address of a subroutine (usually in your code) to something so that something can call the passed subroutine the subroutine would often be called a callback.

Typically used for things like a list iterating routine where the callback would be called for each item in the list.

It's just windows hyperbola. Click a (say) button somewhere and the ID number you gave the button is stored on the "message" stack. At some point in your prog' you may wish to rummage through the messages to see if that particular number has turned up. If you've a PowerBasic for windows, the help file makes a (bad!) effort to describe it. regards john

That's a flag. Here's a good explanation of callbacks:

formatting link

Best,

Mike Monett

My (perhaps non-professional-programmer) definition of that is "relocatable" or "PIC" (position independent) code.

"Pure" code is code that has no associated statics and if of course not self-modifying, so that it can be executed by multiple threads without hassle.

John

Well.....I guess if it were to be really pure code, all addresses would have to be relative to the instruction counter. ;-) We used to call this floatable code as it could be just plunked into memory anywhere and executed.

A simple flag does not constitute a callback, what you are describing is simply persistent memory.

Callbacks are used when a routine (typically event driven), doesn't know what else needs to be done for an event. All it knows is when the event occurs, if there is a procedure address defined, to call it (back).

If you look at publish/subscribe, you have a multiple call back situation. Every client subscribes to the event by passing an execution address which the publisher (server) keeps in a list. When the event occurs, the server "calls back" all the functions passed by the subscribing clients.

Of course, publish/subscribe can also be done with messages or signals, too. The end result is pretty much the same. (Though nigglers will tell you the direct call back has threading and context issues...)

Rufus

I read in sci.electronics.design that John Larkin wrote (in ) about 'what's a callback?', on Mon, 20 Dec 2004:

A veritable model of recidivism!

Regards, John Woodgate, OOO - Own Opinions Only. The good news is that nothing is compulsory. The bad news is that everything is prohibited. http://www.jmwa.demon.co.uk Also see http://www.isce.org.uk

Not even remotely true, let alone possible to compile. The function

*must* exist, however you can select a function and pass a pointer at runtime.

You can't even compile a function in C++ without an implementation.

I think there's a terminology problem, here.

Prototype:

Function(int num, double, mag);

Definition - this is implementation:

Function(int num, double, mag) { // some crap code - or none at all return num; //default return is int :) }

Even an empty function is an *implementation* of a function.

I can write:

call bogus_pointer

for PIC and as long as there's a label "bogus_pointer", it'll go there. That's an implementation. But that doesn't mean it won't execute right on past the return that I forgot to include and f*ck everything up.

So I include the return stmnt and everything's fine.

But to get back OT :) a good example of a call back is the function pointer that must be passed to the "CreateWindow()" function in winders API. It's the "WndProc" function in the prototype.

When winders OS needs to send a message (you clicked the little "x" in the text editor) to a window it calls that WndProc function with a handle to that window.

The callback can be static, i.e., it is shared by all processes calling it.

The neat thing is that in the WndProc function, you can create a controller object that stores (via SetWidowsLong(hWnd, ...) you pass the window handle to identify which window) a pointer to itself in the window's reserved data space.

Now the callback can access the controller object for that particular window (say you have 2 text edit windows open in the same app) and check whether you saved that text file yet. Or whatever.

But f*ck all that noise. Just use wxWidgets ! :) That's open source and cross platform and used by major corps.

-- Best Regards, Mike

My illustrative example is a cooking school. One big recipe is posted on the wall, and lots of students are reading it and cooking, each at their own pace. They maintain their own local variables, the stuff in their pots. The code remains pure as long as nobody splashes anything on it.

John

Good grief, but that's hairy stuff. No wonder Windows is such a flakey pos. Makes me glad I program in assembly, where everything's in plain sight.

As I now recall, the first time I encountered the "callback" concept it was in a realtime assembly-language app. If an ISR didn't have time to finish something, it poked a pointer to the "rest" of its code somewhere and let the RTOS execute that later when resources were available. DECs later OSs (RSXnn and VMS, I think) had a "fork" facility that was similar.

John

John

Something has to be declared or it won't compile. I know, that's not a definition, just a generic function pointer. As you go on, it becomes more clear what you're trying to say (I practiced this same excersize with Kevin :) ) so don't feel compelled to comment on all my comments.

That's called function overloading and another way is polymorphism.

You can't *link* a function call to a function with no definition, If it's *declared" in a header or somewhere "in scope", it will

*compile* but if the definition hasn't been written, the linker won't find it's entry point in any modules and it won't *link*. But that's not a generic function pointer I'm talking about.

IOW, you can't assign a *valid* pointer at runtime unless the function is defined somewhere.

pfunc = atan;

won't work if the linker can't find atan.

pfunc = NULL;

pfunc = atan;

function(pfunc);

groovy, now hit "execute".

As I said, I can pass any bogus pointer in a function. The fact is, that function must have been defined (implemented) somewhere or it won't link. At design time, not run time. You can grab a valid pointer at runtime, but there *will be no valid pointer unless the function was implemented and compiled in a module that the linker can see.*

Period.

None of this changes the fact that it won't link. Won't even compile without a declaration.

function(void){}

void (*pfunc) ();

function(pfunc);

This will compile and link, but if you run this code, you have to assign a value (address) to the function pointer pfunc and you can't get that address if it's stilll vaporware.

None of this changes the fact that this ain't the definition of a callback function.

This is funny. I just typed __define callback function__ into google and didn't get any returns about phones.

formatting link

A callback function is one that is not invoked explicitly by the programmer; rather the responsibility for its invocation is delegated to another function that receives the callback function's address.

Period.

where's the linker gonna get the damn valid pointer from, it's ass?

Good. Now click "Execute". Oh. You're waiting on another group to implement your function? So you wrote what's known to me as a "stub". You could just as easily write an empty function if you don't need the flexibility of function pointers.

say

func(){}

function(func);

and the function "function" will get the pointer to func and execute it as a "callback". It's still a callback regardless of whether it's implemented.

- Best Regards, Mike

Like when the code executes it. You're talking about an event with a callback. Normally you wait on that in a thread callback function.

Example: My sound recorder/scope. The soundcard API funcs set an "Event" when there's data ready. I passed the address of a callback to whatever it was. The callback function (I wrote) sets an event and my processing thread (also has a callback) deals with the data when it returns from WaitForSingleOblect(my_event_handle) . I think I used an unneccessary indirection there, but wtf?

It would have been better to get a handle to that event and just wait on it in a thread callback.

pass the thread callback func pointer to the API func.

then in my thread callback:

WaitForSingleObject(HANDLE event_handle);

But you need the event handle. So I set my own event in a separate callback. Oh! I can't pass the thread callback to the api because it gets called when the thread is created and the thread terminates when the callback function returns.

Thanks for the refresher.

Best Regards, Mike

That's called static linking.

Best Regards, Mike

Reentrant code means that a program can have more than one thread executing concurrently.

formatting link

Best Regards, Mike

What a strange thread. Full of misinformation such as this.

Steve

formatting link

Right. As opposed to "absolute", IIRC.

"Static" referes to local variables that retain their values between calls. Static linking of a function (declared in a class declaration) means that all instances of that class use the same function at the same location.

My def?

Reentrant code means that a program can have more than one thread executing concurrently.

formatting link

Eh? Kinda general really.

If you do something to modify a variable and another thread executes the function it may or may not get a valid value. First, "concurrently". It's an illusion for a single processor system. They get a time slice. But when the threads pause, the code where execution left off is reentered.

Best Regards, Mike

A callback is a function call to a fuction that at design time does not yet exist.

Rene

Ing.Buero R.Tschaggelar - http://www.ibrtses.com & commercial newsgroups - http://www.talkto.net

Ah. Thanks. I didn't stop to think that templates are the way to deal with unknown return types. Problem is that you can't actually use that kind of function without passing the type as a template parameter.

I had a prob with a template in a dll. It wouldn't link because the implementation wasn't there.

Like

dll header template class MyClass{}

The program wouldn't link because there was no implementation.

I couldn't declare

MyClass myClass;

Best Regards, Mike

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required