Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a C++ class member function as a C callback function

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:

  1. First of all is it possible to register a C++ class memeber function like I am trying to do and if so how? (I read 32.8 at http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html. But in my opinion it does not solve the problem)
  2. Is there a alternate/better way to tackle this?
like image 993
Methos Avatar asked Jun 16 '09 10:06

Methos


People also ask

How do you write a callback function in C?

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.

How do you call a class member function?

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.

How do I register a callback function in CPP?

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.

Why do we need callback functions in C?

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).


2 Answers

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.

like image 115
sharptooth Avatar answered Sep 21 '22 08:09

sharptooth


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.

like image 43
Anne van Rossum Avatar answered Sep 21 '22 08:09

Anne van Rossum