Suppose we have some kind of C style API like this:
void register_callback(target, callback_function);
, where target
is some kind of object, e.g. a server, and call_back
is required to be a function pointer.
Now we want to adapt (more precisely, add a wrapper layer. We have no access to the underlying C code, as it is a third-party library) this API to C++. We want OOP, so we make the target into a class:
class Target {
Target(): target() { register_callback(target, callback_function_member) }
private:
target_t target;
void callback_function_member (param_t parameter) { /* a set of things to do with the members */ }
// other members
}
We probably want to make the callback a member function as above, because it (in some cases) is closely tied with the instance. But this won't work. There is no way to adapt member function into a function pointer (see, e.g. Pointers to Member Functions).
And all solutions I found on the internet (including the previous one) only deals with the case where only one instance is responsible for the job. There we can specially write a wrapper function (see 1) or static function of a wrapper class.
The problem is, what if we want multiple instances, and furthermore, dynamic creation of them? You can write a wrapper function or class for each instance, like
Target *pTarget;
void wrapper(param_t parameter) {
pTarget->callback_function_member(parameter);
}
int main() {
Target myTarget();
pTarget = &myTarget();
myTarget.register(wrapper);
// some work
return 0;
}
But you cannot write a function manually for each instance that is dynamically created. And it does not seem possible to pass any kind of information into the global function (e.g., store the instances in a global container, but how to pass the index when called?).
std::bind
is close to the solution (whose existence is unknown to me), but the critical problem is that the return value of std::bind
cannot be cast into a function pointer. Using target<type_of_function_pointer>()
of std::function
gets me a nil
, as the type does not match. When I pretend it to be a function pointer and passed it directly, a segfault happens.
Is this possible after all? Or is my goal just misled? What is the canonical way of dealing with this problem?