Using libuv inside classes
Asked Answered
E

1

5

I am trying to write a nodejs bindings for a C++ library and I seem to have hit a roadblock.

I am working on trying to make all the calls to the C++ library asynchronous and thats why I am using libuv. I am basically following this tutorial.

I want to be able to call class member functions from libuv's uv_queue_work. Have a look at this code --

class test {
  private:
    int data;
    void Work(uv_work_t *req);
    void After(uv_work_t *req);
  public:
    Handle<Value> Async(const Arguments& args) {
      HandleScope scope;
      Local<Function> callback = Local<Function>::Cast(args[0]);
      int status = uv_queue_work(uv_default_loop(), **something**, Work, After);
      assert(status == 0);
      return Undefined();
    }
};

Basically I expect the Work and After functions to work on the data element of the class. However this doesnt seem to work. I have tried typecasting the pointers to Work and After after from type void test::(*)(uv_work_t*) to void (*)(uv_work_t*). But that also doesnt seem to work.

Could you guys give me some tips on how to work around this??

Eager answered 20/8, 2012 at 9:28 Comment(0)
S
7

So as you've realized, you cannot call the member functions directly.

The second argument "something" is of type uv_work_t, which has a member "void* data".

What you will need to do is create static methods inside your class for "Work" and "After", create a uv_work_t structure, and assign data to "this".

Once that is done inside your static "Work" and "After" methods you do a static cast on "req->data" (To your class type) and then call your member functions.

For example:

uv_work_t* baton = new uv_work_t();
baton->data = this;
int status = uv_queue_work(uv_default_loop(), baton, StaticWork, StaticAfter);

And then in the static methods

test* myobj = static_cast<test>(req->data);
myobj->Work();

And similar code for the StaticAfter function

Subhuman answered 21/8, 2012 at 12:33 Comment(2)
well yes.... I was trying something of the sort... but wont this lead to a whole lot of extra code being written? i mean u will have one function for the javascript calls, two for the uv_queue_work handlers and then one more which actually does the job? so if i already have a large codebase which does the job (but without the async calls).... it would be similar to rewriting the entire thing!!!Eager
I can't remember the exact implementation details, but I managed to implement a base class using templates along with a templated function pointer to pull out a lot of common code... However you do still end up with a lot of "extra" code :(Subhuman

© 2022 - 2024 — McMap. All rights reserved.