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:
- 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)
- Is there a alternate/better way to tackle this?
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):
This example is complete in the sense that it compiles:
You will need the
c++11
flag. In the code you see thatregister_with_library(func)
is called, wherefunc
is a static function dynamically bound to the member functione
.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 ofclass A*
type.The problem is that method != function. The compiler will transform your method to something like that:
So, it's sure you can't pass it, because the class instance can't be passed as argument. One way to work around is to make the method as static, this way it would have the good type. But it won't any class instance, and access to non-static class members.
The other way is to declare a function with a static Pointer to a A initialised the first time. The function only redirect the call to the class :
Then you can register the callback function.
Well ...if you are on a win32 platform there is always the nasty Thunking way ...
Thunking in Win32: Simplifying callbacks to non-static member functions
It is a solution but I don't recommend using it.
It has a good explanation and it is nice to know it exists.
The problem with using a member function is that it needs an object on which to act - and C doesnt know about objects.
The easiest way would be to do the following: