I have a C library that needs a callback function to be registered to customize some processing. Type of the callback function is int a(int *, int *)
.
I am writing C++ code similar to the following and try to register a C++ class function as the callback function:
class A { public: A(); ~A(); int e(int *k, int *j); }; A::A() { register_with_library(e) } int A::e(int *k, int *e) { return 0; } A::~A() { }
The compiler throws following error:
In constructor 'A::A()', error: argument of type ‘int (A::)(int*, int*)’ does not match ‘int (*)(int*, int*)’.
My questions:
We can define it in other words like this: If the reference of a function is passed to another function argument for calling, then it is called the callback function. In C we have to use the function pointer to call the callback function. The following code is showing how the callback function is doing its task.
A member function is declared and defined in the class and called using the object of the class. A member function is declared in the class but defined outside the class and is called using the object of the class.
To be sure that the callback function scheme is asynchronous, make the main input to the code, the input to the callback function; make the main output of the code, the output of the callback function; store the output of the callback function in a variable or data structure.
Callback functions are an essential and often critical concept that developers need to create drivers or custom libraries. A callback function is a reference to executable code that is passed as an argument to other code that allows a lower-level software layer to call a function defined in a higher-level layer(10).
You can do that if the member function is static.
Non-static member functions of class A have an implicit first parameter of type class A*
which corresponds to this pointer. That's why you could only register them if the signature of the callback also had the first parameter of class A*
type.
You can also do this if the member function is not static, but it requires a bit more work (see also Convert C++ function pointer to c function pointer):
#include <stdio.h> #include <functional> template <typename T> struct Callback; template <typename Ret, typename... Params> struct Callback<Ret(Params...)> { template <typename... Args> static Ret callback(Args... args) { return func(args...); } static std::function<Ret(Params...)> func; }; template <typename Ret, typename... Params> std::function<Ret(Params...)> Callback<Ret(Params...)>::func; void register_with_library(int (*func)(int *k, int *e)) { int x = 0, y = 1; int o = func(&x, &y); printf("Value: %i\n", o); } class A { public: A(); ~A(); int e(int *k, int *j); }; typedef int (*callback_t)(int*,int*); A::A() { Callback<int(int*,int*)>::func = std::bind(&A::e, this, std::placeholders::_1, std::placeholders::_2); callback_t func = static_cast<callback_t>(Callback<int(int*,int*)>::callback); register_with_library(func); } int A::e(int *k, int *j) { return *k - *j; } A::~A() { } int main() { A a; }
This example is complete in the sense that it compiles:
g++ test.cpp -std=c++11 -o test
You will need the c++11
flag. In the code you see that register_with_library(func)
is called, where func
is a static function dynamically bound to the member function e
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With