How do C library writers support callbacks?

This is common pattern of design that one sees with C libraries to solve this problem:

  • The library writer needs to make it possible for the user of the library to consume data coming back from say:

    • Reading off a socket or file.

    • Parsing a document - say XML or JSON

    • etc.

So generally the user of the library needs to:

  • Receive callbacks from the library

  • Have a means of putting the information from those callbacks in an appropriate part of the users application.

So the common way we do it in C is this, here is the API:

/* C API */ typedef void (CLIBcallback*)(void* pUserPointer, const char* pSomeDataInCallback); void CLIBstartProcess(void* pUserPointer, CLIBcallback* pCallback);

And this is how a user application might use this API.

struct FOOconsumer{ int Count; }; void FOOcallback(void* pUserPointer, const char* pSomeDataInCallback); int main(){ FOOconsumer Foo; Foo.Count = 0; CLIBstartProcess((void*)&Foo, &FOOcallback); } void FOOcallback(void* pUserPointer, const char* pSomeDataInCallback){ FOOconsumer* pConsumer = (FOOconsumer*)pUserPointer; pConsumer.Count = pConsumer.Count + 1; }

See how:

  • We use the pUserPointer to give the address of the Foo instance of the FOOconsumer struct

  • The library writer passes this through to the callback function as void* pointer

  • The application writer can then cast back to a FOOconsumer pointer

  • And thus consume the information.