Hi, I'm trying to figure out how to use UV in my C++ project in a way that the UV callbacks are instance methods of my classes.
I know that a UV callback must be a static method (and not a C++ class member method) so I use std::bind. However it fails:
-------------------------------------------------------------------
// Worker constructor.
Worker::Worker() {
this->number = 42;
this->loop = new uv_loop_t;
uv_loop_init(this->loop);
this->idle = new uv_idle_t;
uv_idle_init(this->loop, this->idle);
auto callback = std::bind(&Worker::Callback, this, std::placeholders::_1, std::placeholders::_2);
uv_idle_start(this->loop, callback);
uv_run(this->loop, UV_RUN_DEFAULT);
}
// Callback to be called by the UV idle.
void Worker::Callback(uv_idle_t* handle, int status) {
// do something with Worker instance members:
printf("my number is %d\n", this->number);
}
-------------------------------------
Unfortunately this does not compile (G++ 4.8 with -std=c++11):
Worker.cpp: In member function 'void Worker::Run()':
Worker.cpp:77:36: error: cannot convert 'std::_Bind<std::_Mem_fn<void (Worker::*)(uv_idle_s*, int)>(Worker*, std::_Placeholder<1>, std::_Placeholder<2>)>' to 'uv_idle_cb {aka void (*)(uv_idle_s*, int)}' for argument '2' to 'int uv_idle_start(uv_idle_t*, uv_idle_cb)'
uv_idle_start(this->loop, callback);
I have a working solution that I just don't like:
---------------------------------------------
std::function<void(uv_idle_t*, int)> callback;
void wrapper(uv_idle_t* handle, int status) {
callback(handle, status);
}
Worker::Worker() {
this->number = 42;
this->loop = new uv_loop_t;
uv_loop_init(this->loop);
this->idle = new uv_idle_t;
uv_idle_init(this->loop, this->idle);
auto callback = std::bind(&Worker::Callback, this, std::placeholders::_1, std::placeholders::_2);
uv_idle_start(this->loop, wrapper); // Note that here I pass wrapper instead of callback.
uv_run(this->loop, UV_RUN_DEFAULT);
}
// Callback to be called by the UV idle.
void Worker::Callback(uv_idle_t* handle, int status) {
// do something with Worker instance members:
printf("my number is %d\n", this->number);
}
---------------------------------------------
Do I miss something in my first (and not working) approach?
NOTE: I would prefer not to store "this" (the pointer to the current Worker instance) into the handler->data field.
Thanks a lot.