Libasync tutorial

Lesson 2: Callbacks with parameters

Prev Index Next

The Hello, World! example demonstrated a very simple callback. This lesson demonstrates how you can pass parameters to callback functions.

examples/param1.C

 1:   #include "str.h"
 2:   #include "async.h"
 3:   
 4:   void
 5:   doprint(str foo)
 6:   {
 7:     warn << foo << "\n";
 8:     exit(0);
 9:   }
10:   
11:   int
12:   main(int argc, char *argv[])
13:   {
14:     async_init();
15:     delaycb(5, 0, wrap(doprint, "Hello, World!"));
16:     amain();
17:   }

This example is very similar to the "Hello, World!" example in Lesson 1. However, in this case we have a doprint function that can print out any string; not just "Hello, World!". Notice the use of a str object in doprint.

The delaycb call is very similar to the previous example, but now we pass to wrap a function (doprint) and a parameter ("Hello, World!") to doprint. You can pass up to [???] parameters to a callback function using wrap. If you need to pass more, you probably designed your program the wrong way, but you could work your way around it by defining a struct or class with all the necessary parameters as member variables and passing an instance of that struct or class.

Here's an example that passes multiple parameters to a callback:

examples/param2.C

 1:   #include "str.h"
 2:   #include "async.h"
 3:   
 4:   void
 5:   doprint(str foo, int bar)
 6:   {
 7:     warn << foo << " : " << bar << "\n";
 8:   }
 9:   
10:   int
11:   main(int argc, char *argv[])
12:   {
13:     int i;
14:   
15:     async_init();
16:     for(i=1; i<=3; i++)
17:       delaycb(i, 0, wrap(doprint, "Hello, World!", i));
18:     delaycb(i, wrap(exit, 0));
19:     warn << "done looping\n";
20:     amain();
21:   }

First of all, notice that warn can print out int-s in addition to str objects. The if statement on line 9 ensures that the program exits after printing the third "Hello, World!".

The for-loop on line 17 calls delaycb three times. One with a delay of 1 second, one 2 seconds, and one 3 seconds. You'll notice that the "done looping" message shows up immediately, demonstrating that delaycb returns immediately and doesn't block the program, like sleep would.

You can have multiple pending callback when using delaycb. In other words: later calls to delaycb do not disable earlier ones.

Object methods as callback functions

You can also use objects methods as callback functions.

examples/oowrap.C

 1:   #include "async.h"
 2:   
 3:   class foo {
 4:   public:
 5:     void fn(str s) {
 6:       warn << s;
 7:     }
 8:   
 9:     foo() {
10:       delaycb(1, 0, wrap(this, &foo::fn, "constructor\n"));
11:     }
12:   
13:     ~foo() {
14:       warn << "destructor\n";
15:     }
16:   };
17:   
18:   
19:   void
20:   stop(foo *f)
21:   {
22:     delete f;
23:     exit(0);
24:   }
25:   
26:   int
27:   main()
28:   {
29:     async_init();
30:   
31:     foo *bar = New foo();
32:     delaycb(2, 0, wrap(bar, &foo::fn, "Hello, World!\n"));
33:     delaycb(3, 0, wrap(stop, bar));
34:     amain();
35:   }

Ignore the fact that we use New instead of new on line 31. We'll explain it in Lesson 4.

On line 10, foo's constructor sets a callback to its own fn method. The first parameter is a pointer to the object, the second parameter is the method within the object.

Line 32 has a similar example.

Prev Index Next

Back to main.