Home > Software design >  Using callbacks in C
Using callbacks in C

Time:09-22

I'm working on a project in C , but at some point in the application it fails and generates a core dump. The application uses a couple of classes, which for the purposes here I'm concentrating on one of the classes, which I'm calling A, and is instantiated as object a. This has a large number of member functions, of which at the moment only a few are being used, but one of these generates a log to produce diagnostics to be used for debugging. I want to use this to find out why the application is failing.

The project is to put together code that invokes the various member functions, and although I have access to the source code and some limited documentation, none of the code can be changed, with all changes being in the code that makes use of the classes and invokes the member functions. The member function in question is:

void enable_log (log_callback callback, void * user_data = nullptr)

where the 1st argument callback contains the message and 2nd argument is optional. For now it can be set to nullptr, so would be invoked as:

a.enable_log(callback, nullptr);

From this documentation it's not at all clear what exactly callback is. However, in looking at the source code this is:

using log_callback = void (*)(const std::string& message, void* user_data);

in a header file, where log_callback is an alias for const std::string& if I understand this correctly.

I already have dummy classes on a platform using Visual Studio 2019 with some test member functions to simulate invoking the member functions on a remote Linux server, but I'm unable to find a way of making use of the member function above. I added the test member function to the dummy class as follows:

void enable_log(const std::string& callback, void* user_data = nullptr) {
    callback = "ABCD";
}

which is supposed to generate a test string which is returned, such that in the real application this string will have diagnostic information that will be written to a file. However, the "=" is an error.

The idea is that in the main function an empty string will be declared, then enable_log() should populate this string, which can be printed out.

I've spent some time looking at various resources, including Stackoverflow, but I cannot find a way of returning a string with the information that can be printed out. I need a simple way to simulate this, and as I said above, I must not change the source code of the real member function, so the simulated member function has to produce a string in the same way. How is this done? Some advice would be appreciated.

CodePudding user response:

Callback, in simple words, is some function that will be called later at some point. Example:

void callback_fn(int a);

using callback_t = (void)(*)(int a);
void some_func(callback_t);

You can use some_func() like so:

some_func(callback_fn);

Full example here: https://godbolt.org/z/ET3GhfYrv

For your usecase the parameters of the callback are slightly different. Here's how to read the syntax:

using log_callback = // this just creates an alias for whatever is on the right handside

void // the return type of the "callable" should be void

(*) // this tells us that it is a function pointer

(const std::string& message, void* user_data) // These are the arguments the callable takes. It is a "std::string" and a "void *"

To use this, just create a free function with the same signature:

void callable(const std::string &msg, void *userData = nullptr)
{
   // msg is the data sent by the function. use it in whatever way
   // you want.
   std::cout << msg << '\n';
}

// Pass it to the enable_log
enable_log(callable);
  • Related