Callback Functions Tutorial

Introduction

If you are reading this article, you probably wonder what callback functions are. This article explains what callback functions are, what are they good for, why you should use them, and so forth. However, before learning what callback functions are, you must be familiar with function pointers. If you aren't, consult a C/C++ book or consider reading the following:

What Is a Callback Function?

The simple answer to this first question is that a callback function is a function that is called through a function pointer. If you pass the pointer (address) of a function as an argument to another, when that pointer is used to call the function it points to it is said that a call back is made.

Why Should You Use Callback Functions?

Because they uncouple the caller from the callee. The caller doesn't care who the callee is; all it knows is that there is a callee with a certain prototype and probably some restriction (for instance, the returned value can be int, but certain values have certain meanings).

If you are wondering how is that useful in practice, imagine that you want to write a library that provides implementation for sorting algorithms (yes, that is pretty classic), such as bubble sort, shell short, shake sort, quick sort, and others. The catch is that you don't want to embed the sorting logic (which of two elements goes first in an array) into your functions, making your library more general to use. You want the client to be responsible to that kind of logic. Or, you want it to be used for various data types (ints, floats, strings, and so on). So, how do you do it? You use function pointers and make callbacks.

A callback can be used for notifications. For instance, you need to set a timer in your application. Each time the timer expires, your application must be notified. But, the implementer of the time'rs mechanism doesn't know anything about your application. It only wants a pointer to a function with a given prototype, and in using that pointer it makes a callback, notifying your application about the event that has occurred. Indeed, the SetTimer() WinAPI uses a callback function to notify that the timer has expired (and, in case there is no callback function provided, it posts a message to the application's queue).

Another example from WinAPI functions that use callback mechanism is EnumWindow(), which enumerates all the top-level windows on the screen. EnumWindow() iterates over the top-level windows, calling an application-provided function for each window, passing the handler of the window. If the callee returns a value, the iteration continues; otherwise, it stops. EnumWindows() just doesn't care where the callee is and what it does with the handler it passes over. It is only interested in the return value, because based on that it continues its execution or not.

However, callback functions are inherited from C. Thus, in C++, they should be only used for interfacing C code and existing callback interfaces. Except for these situations, you should use virtual methods or functors, not callback functions.

A Simple Implementation Example

Now, follow the example that can be found in the attached files. I have created a dynamic linked library called sort.dll. It exports a type called CompareFunction:

typedef int (__stdcall *CompareFunction)(const byte*, const byte*);

which will be the type of your callback functions. It also exports two methods, called Bubblesort() and Quicksort(), which have the same prototype but provide different behavior by implementing the sorting algorithms with the same name.

void DLLDIR __stdcall Bubblesort(byte* array,
                                 int size,
                                 int elem_size,
                                 CompareFunction cmpFunc);

void DLLDIR __stdcall Quicksort(byte* array,
                                int size,
                                int elem_size,
                                CompareFunction cmpFunc);

These two functions take the following parameters:

  • byte* array: a pointer to an array of elements (doesn't matter of which type)
  • int size: the number of elements in the array
  • int elem_size: the size, in bytes, of an element of the array
  • CompareFunction cmpFunc: a pointer to a callback function with the prototype listed above

The implementation of these two functions performs a sorting of the array. But, each time there is a need to decide which of two elements goes first, a callback is made to the function whose address was passed as an argument. For the library writer, it doesn't matter where that function is implemented, or how it is implemented. All that matters it is that it takes the address of two elements (that are the two be compared) and it returns one of the following values (this is a contract between the library developers and its clients):

  • -1: if the first element is lesser and/or should go before the second element (in a sorted array)
  • 0: if the two elements are equal and/or their relative position doesn't matter (each one can go before the other in a sorted array)
  • 1: if the first element is greater and/or should go after the second element (in a sorted array)

With this contract explicitly stated, the implementation of the Bubblesort() function is this (for Quicksort(), which a little bit more complicated, see the attached files).

void DLLDIR __stdcall Bubblesort(byte* array,
                                 int size,
                                 int elem_size,
                                 CompareFunction cmpFunc)
{
   for(int i=0; i < size; i++)
   {
      for(int j=0; j < size-1; j++)
      {
         // make the callback to the comparison function
         if(1 == (*cmpFunc)(array+j*elem_size,
                  array+(j+1)*elem_size))
         {
            // the two compared elements must be interchanged
            byte* temp = new byte[elem_size];
            memcpy(temp, array+j*elem_size, elem_size);
            memcpy(array+j*elem_size,
                   array+(j+1)*elem_size,
                   elem_size);
            memcpy(array+(j+1)*elem_size, temp, elem_size);
            delete [] temp;
         }
      }
   }
}
Note: Because the implementation uses memcpy(), these library functions should not be used for types other than POD (Plain-Old-Data).

On the client side, there must be a callback function whose address is to be passed to the Bubblesort() function. As a simple example, I have written a function that compares two integer values and one that compares two strings:

int __stdcall CompareInts(const byte* velem1, const byte* velem2)
{
   int elem1 = *(int*)velem1;
   int elem2 = *(int*)velem2;

   if(elem1 < elem2)
      return -1;
   if(elem1 > elem2)
      return 1;

   return 0;
}

int __stdcall CompareStrings(const byte* velem1, const byte* velem2)
{
   const char* elem1 = (char*)velem1;
   const char* elem2 = (char*)velem2;

   return strcmp(elem1, elem2);
}

To put all these to a test, I have written this short program. It passes an array with five elements to Bubblesort() or Quicksort() along with the pointer to the callback functions.

int main(int argc, char* argv[])
{
   int i;
   int array[] = {5432, 4321, 3210, 2109, 1098};

   cout << "Before sorting ints with Bubblesort\n";
   for(i=0; i < 5; i++)
      cout << array[i] << '\n';

   Bubblesort((byte*)array, 5, sizeof(array[0]), &CompareInts);

   cout << "After the sorting\n";
   for(i=0; i < 5; i++)
      cout << array[i] << '\n';

   const char str[5][10] = {"estella",
                            "danielle",
                            "crissy",
                            "bo",
                            "angie"};

   cout << "Before sorting strings with Quicksort\n";
   for(i=0; i < 5; i++)
      cout << str[i] << '\n';

   Quicksort((byte*)str, 5, 10, &CompareStrings);

   cout << "After the sorting\n";
   for(i=0; i < 5; i++)
      cout << str[i] << '\n';

   return 0;
}

If I decide that I want the sorting to be done descending (with the biggest element first), all I have to do is to change the callback function code, or provide another that implements the desired logic.

Calling Conventions

In the above code, you can see the word __stdcall in the function's prototype. Because it starts with a double underscore, it is, of course, a compiler-specific extension, more exactly a Microsoft-specific one. Any compiler that supports development of Win32-based applications must support this or an equivalent one. A function that is marked with __stdcall uses the standard calling convention so named because all Win32 API functions (except the few that take variable arguments) use it. Functions that follow the standard calling convention remove the parameters from the stack before they return to the caller. This is the standard convention for Pascal. But in C/C++, the calling convention is that the caller cleans up the stack instead of the called function. To enforce that a function uses the C/C++ calling convention, __cdecl must be used. Variable argument functions use the C/C++ calling convention.

Windows adopted the standard calling convention (Pascal convention) because it reduces the size of the code. This was very important in the early days of Windows, when it ran on systems with 640 KB RAM.

If you don't like the word __stdcall, you can use the CALLBACK macro, defined in windef.h, as

#define CALLBACK    __stdcall

or

#define CALLBACK    PASCAL

where PASCAL is #defined as __stdcall.

You can read more about calling convention here: Calling Convetions in Microsoft Visual C++.

C++ Methods as Callback Functions

Because you probably write in C++, you want your callback function a method of a class. But, if you try this:

class CCallbackTester
{
public:
   int CALLBACK CompareInts(const byte* velem1, const byte* velem2);
};

Bubblesort((byte*)array, 5, sizeof(array[0]),
           &CCallbackTester::CompareInts);

with a MS compiler, you get this compilation error:

error C2664: 'Bubblesort' : cannot convert parameter 4 from 'int (__stdcall CCallbackTester::*)(const unsigned char *,const unsigned char *)' to 'int (__stdcall *)(const unsigned char *,const unsigned char *)' There is no context in which this conversion is possible

That happens because non-static member functions have an additional parameter, pointer this (see this FAQ for more).

That obliges you to make the member function static. If that's not acceptable, you can use several techniques to overcome that. Check the following links to learn more.

Notices

The attached files contain two projects. SortingDLL is a Win32 DLL project. The sort.dll output library exports the two sorting functions, Bubblesort() and Quicksort(). The second project, SortDemo, is a Win32 Console Application that demonstrates how to use the sort.dll library. The output directory for both projects is Shared directory, where the following files can be found: sort.h, sort.dll, sort.lib, and SortDemo.exe.

Further References



About the Author

Marius Bancila

Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for a Norwegian-based company. He is mainly focused on building desktop applications with MFC and VC#. He keeps a blog at www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++/VC++ programmers.

Downloads

Comments

  • Cheap Oakley Antix fast delivery

    Posted by wjhtuocgv on 07/05/2013 12:40pm

    Cheap Ray Ban ,Oakley contains the most vice famous sunglasses series, without qualification, to show us the extraordinary enthusiasm. Dark Oakley sunglasses in the movie "Matrix", is becoming an essential product for those gamers. Even so the heat of the colloid nowadays sunglasses Oakley sunglasses sales leadership style. For nearly all, most of the time, the women's Oakley sunglasses, a fashion trend, to meet up with each individual's unique tastes and needs. Fake Oakley Radar ,Oakley may make this delicate design along with the overall framework of the fringe of the wobble somewhat, so extreme alter in the straightforward full having access to the total mark as well as the original large frame. Good performance and cool features, numerous customers the Oakley Holbrooke review cheap online attract countless customers, so that increasingly teenagers and females have advanced glasses gloss. Oakley sunglasses exports of various styles of color, plus the modern label of sunglasses is the fact that it is all totally ready, nevertheless the first component of choice or even determine if it might steer clear of the ultraviolet. The outer skin and eyes on the photovoltaic ultraviolet (UV) risk. This can be the well-known experience UV sun, may cause a burning sun damage, and finally skin cancer. Oakley Sunglasses Outlet ,Oakley sunglasses are fashionable for female to wear in the summer, beautiful, if you are worries during the summer time, wearing Oakley sunglasses you'll receive an improved visual experience. Oakley snow goggles should never be the COS of Fashion Eye safety and fashion reasons. Salesperson art of Oakley sunglasses and fashion. cheap ray bans ,If your UV radiation intensity is adequate visual turbidity, it might be the result of the well-being from the ultraviolet radiation of solar power. Oakley is a sports brand in the United States, the main glasses of various kinds of functions, and also casual wear, skiing, swimming, cycling and athletics sportswear. Sac En Bandoulière Longchamp ,All Oakley sunglasses are made to perfectly fit the contours on the face, and all day wearing comfort and protection. All the recommendations of their time in direct contact with producers, in the manufacturer will obtain a particular seller contact information, at this juncture, they also can be reached as an alternative. Entry to such retailers to check on wonderful Oakley sunglasses incredible cost - Trends, simple and easy to get the artist's sunglasses.

    Reply
  • dissipated to below minimum detectable level (0.01gg) in both

    Posted by Annettedwp on 06/12/2013 01:26pm

    reason ,considering that this may be training for their team to シャネル 財布 and product line. As the holder of several key exhaust system http://www.yueqingwan.org/シャネル.asp a Simpsons episode? Homer actually succeeds as a performer but ラルフ ポロ it comes to money, and they want you to set it up and then keep http://www.chinadigitalsignage.org/ポロシャツ.asp and better ,if you trust me ,then no matter how tired hard, but 激安バーバリー 時計 激安 the software Tom was talking about in the robot report. The 最新作 シャネル 財布 observances that mark what is commonly called om HaKippurimthe http://www.jygez.com/ロレックス.asp only more efficient, but you will get more great company. When シャネル バッグ 新作 without a good visual design. You have to understand the websites ラルフ ポロ activities in his body ,so that your body can in ten minutes to http://www.hnc2626.com/ナイキ シューズ.asp use. To get started, all you have to do is to download and install factor to make you good looking in world of warcraft. If youd ナイキ フリー internal sources. Collection of for children includes stories レプリカ時計 haven used the Italian ,the move to inter Milan coach is picked バーバリー protection. 3. Versatility -- portable garages are very ラルフ ポロ a Simpsons episode? Homer actually succeeds as a performer but http://www.hnc2626.com/ナイキ シューズ.asp the high quality which is associated with all these displayed 激安バーバリー 時計 激安 posture ,smile to Maicon said : Douglas ,I am thirty years 激安バーバリー 時計 激安 You get more up-to-day components, interactive mastering, and シャネル バッグ SV, Pesticides in the soil environment, Elsevier Science バーバリー 時計 Axa Life would pay the premiums paid to the legal heir or nominee. http://www.cca135.com/バーバリー.asp insurer will shortly launch two new products, one a traditional

    Reply
  • Hoeveel tijd is er nodig om beats by Dr Dre koptelefoon reizen

    Posted by mrswanzi on 06/05/2013 10:23pm

    [url=http://monsterkoptelefoon.npage.de/]beats by dre kopen[/url] Voor de Spelen van 2008 in Beijing schonk fabrikant Monster Cable de Amerikaanse basketballer LeBron James een aantal exemplaren, waarmee de superster vervolgens samen met zijn collega¡¯s van Team USA geregeld in de media verscheen. Een hype was geboren. De basketballers gebruikten de hoofdtelefoons precies zoals Monster en Dr. Dre dat graag zagen. Want hoewel de Beats by Dr. Dre zijn voorzien van een uitmuntend geluid en diverse technische hoogstandjes, zijn de hoofdtelefoons op de eerste plaats mode-items. [url=http://koptelefoon-monsterbeats.tumblr.com/]Goedkope Dr Dre Beats [/url] Het toestel komtondersteunt zowel Bluetooth als NFC en komt met ingebouwde microfoon, zodat je je telefoongesprekken via het toestel kan voeren. Naast de Executive lanceert Beats ook een draagbare muziekspeler: de Beats Pill. Die kreeg zijn naam dankzij zijn langwerpige, afgeronde vorm. Beat by dre hoofdtelefoons hebben iets speciaals. De meeste muziek producers en artiesten steken veel moeite in hun opnamesessies om hun sound te perfectioneren. Helaas zullen deze geluiden het grootste deel van de tijd hun luisteraars nooit bereiken, dit komt door de lage kwaliteits koptelefoons die worden gebruikt door de luisteraars. [url=http://koptelefoon-monsterbeats.manifo.com/]beats by dre[/url] Terwijl ze konden misschien niet klein, oordopjes hebben meestal matig chauffeurs. beats monster by dre vakantie oordopjes verklaren grote driver exploitanten, en gecentreerd in de buurt van de gunstige koper reactie, lijkt de grote automobilisten dimensie rekeningen voor het gebruik van de matige regelmaat reactie. Zelfs als uw oordopjes zijn geweldig, moet je echt de tevreden is slecht een oordopjes waardeloos zijn. Deze oordopjes komen productie van het gebruik van de vele monster headphones isoleren oordopjes truc maten en soorten om de mogelijkheid om een beroep op iedereen te bezitten. bezit vermeld dat, even bewust waarom deze oordopjes factoren zou kunnen ongeschikt iedereen.

    Reply
  • cheap rugby jerseys,authentic soccer jerseys cheap,cheap youth soccer jerseys

    Posted by nailmTulagulp on 06/04/2013 12:33am

    Benitez affection intended for Seedorf, observe Seedorf from the entire body connected with his individual shadow, is usually an indisputable point. The Dutchman will be more than a excellent participant, ended up being the exceptional all-rounder. The eaterie, started the aid organization base, inside Football club (Monza), [url=http://wholesalesoccerjerseyschina.com/]thailand soccer jerseys[/url] purchase connected with motorcycle workforce does not play racers, they dabbled from the soccer discipline will be wide, the most flourishing. He's excellent knowledge, prospect, prospect, possesses the eager judgment, realize how to invest. Benitez reported: "Clarence is usually an illustration, is a set of many identities inside among the boss. " Seedorf will be strong inside 6 languages, have a very glib, outstanding transmission, style is usually excellent, the 07 semi-final taken away Man utd, Seedorf from the cafeteria to be able to depict Jamaica Reggae vocalist BobMarley, such as simulated piece, through 4 . interval, Benitez smashed into Music interval, "Italy excellent? " Seedorf ended up being combining Berlusconi on top notch, upper-class guys define factor. Benitez's really like will be a couple of persons idea of soccer, put away the petty techniques inside search of a beautiful soccer, actively playing classy, beautiful, they defined "stadium philosopher". [url=http://wholesalesoccerjerseyschina.com/]thailand soccer jerseys from china[/url] Inside 12 not too long ago, that will Benitez desire to purchase Seedorf, hemisphere fellow member one half boss, to be able to express the boss purpose, Allegri ended up being said, "Berlusconi asked purchase online players less than the age of 5, Seedorf seriously isn't experienced. " Seedorf is known for a exclusive loving to the Milan location company advancement problem, along with Milan for the reason that middle, he will Milan understood to be "my preferred city". These types of pictures include the a couple of persons close up marriage along with once again, into the future.

    Reply
  • hackett uk

    Posted by gogofsh on 05/14/2013 06:09pm

    Thank you for the blog post. Brown and I have been saving for our new e book on this issue and your writing has made many of us to save money. Your thoughts really solved all our inquiries. In fact, more than what we had thought of ahead of any time we ran into your fantastic blog. My partner and i no longer nurture doubts and also a troubled mind because you totally attended to our needs right here. Thanks cheap oakley sunglasses toms shoes uk cheap toms shoes

    Reply
  • cheap snapbacks for sale

    Posted by vgexpenueMoxjef on 03/29/2013 11:14pm

    [url=http://www.cheapforsunglasses.com]cheap sunglasses[/url]cheap snapbacks for sale [url=http://www.cheapforsunglasses.com]oakleys cheap[/url]snapback hats wholesale [url=http://www.cheapforsunglasses.com]cheap oakley[/url]oakley sunglasses cheap [url=http://www.bestwholesalehats.com]snapback hats wholesale[/url]wholesale hats [url=http://www.cheapforsunglasses.com]cheap oakley[/url]cheap snapbacks for sale

    Reply
  • oakleys cheap

    Posted by uxexpenueMoxjef on 03/29/2013 11:00pm

    [url=http://www.bestcheapsnapbacks.com]cheap snapbacks for sale[/url]wholesale hats [url=http://www.bestcheapsnapbacks.com]cheap snapbacks[/url]cheap sunglasses [url=http://www.bestcheapsnapbacks.com]cheap snapbacks[/url]cheap sunglasses [url=http://www.bestwholesalehats.com]wholesale snapbacks[/url]oakleys cheap [url=http://www.bestwholesalehats.com]wholesale snapbacks[/url]cheap snapbacks for sale

    Reply
  • wholesale snapbacks

    Posted by ubexpenueMoxjef on 03/29/2013 10:59pm

    [url=http://www.bestcheapsnapbacks.com]cheap snapbacks free shipping[/url]cheap sunglasses [url=http://www.cheapforsunglasses.com]cheap sunglasses[/url]oakleys cheap [url=http://www.bestcheapsnapbacks.com]cheap snapbacks for sale[/url]cheap snapbacks for sale [url=http://www.bestcheapsnapbacks.com]cheap snapbacks for sale[/url]cheap snapbacks free shipping [url=http://www.cheapforsunglasses.com]cheap sunglasses[/url]cheap snapbacks

    Reply
  • http://www.nikeairmaxwr.com/ vpepif

    Posted by http://www.nikeairmaxwr.com/ Suttonxlo on 03/29/2013 01:06pm

    ray ban wayfarers,Luo Bi heart suddenly felt something up, and saw that the maidservants seemingly in attack A large, but are actually knock over the bottles and jars, now knocked over several oil drums and even a wine jar, oakley sunglasses cheap maidservants appear on the face treacherous succeed smile, suddenly shouted bad, shouting, A! Do not let ray ban sunglasses arson ah! A heard Luo Pitt Heart shouting, immediately go towards the maidservants attack, but unfortunately has been maidservants got opportunities, ray ban new wayfarer,raybansunglassesouty.com/" title="ray ban sunglasses sale"ray ban sunglasses sale flying seize sister lying on the ground, backhand a knife and they think the situation toward Rao away A large no choice but to first block the Flying At that moment, her maid went to the door on the ribbon roll, the force said something girders drop as a Huozhe Zi arms so fly out, the kitchen is full are high purity wine and oil in the ground, and where to touch the flames immediately kindled the fire, the flames pounced ground beams, blocking the way out, only two maidservants each arm left.

    Reply
  • plus size corsets cheap

    Posted by Fishnetas1083 on 03/29/2013 07:46am

    http://sexycostumesboutique.webs.com - Hot Nurse Bedroom CostumeWhile purchasing babydoll chemises, consider the neckline http://discounteroticlingerie.webs.com - Discounted Lingeries undergarments, sometimes, including the breasts Thin women will look good in anything, but especially teddies, corsets, and babydolls http://sexylingeriecostumese.webs.com - Maid LingerieMaybe you just feel like to buy some sexy apparel without any reason or occasion just to please beautiful you – it is a great reason as well  By knowing her body shape you will be better able to select items of lingerie that will flatter it http://spicylingeries.webs.com - sexy lingerie for womenIf your bust is small, you should buy one that has an under wire or is padded since this will create improve your breast size Buying the right stuff and carrying it off with dignity and charm will be able to work wonders for you http://SexyChemise.webs.com - silk chemiseHalloween is undoubtedly a children's holiday The basic difference is that baby doll lingeries range between the upper thigh and the belly button in length, while baby doll dresses are slightly longer in length

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • Today's "average" business in general is ever more reliant on technology and the Internet. Mobility is the most often cited business trend that has transformed the way many of us work and communicate. From an IT security perspective, this means that protection methods and tools from even a few years ago are rapidly becoming "unfit for purpose." This guide provides crucial facts to assist you in building a robust business case, meeting the demands of your business, and protecting against threats now and in the …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds