Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert V8 objects to pointers?

I'm writing a Node application (in TS) that needs to be interfaced with some native library.

I have a library (written in C) - let's consider it's a blackbox - and I'm writing a wrapper using NAN. The library native interface can be simplified into a following functions:

typedef void (*got_message_reply_cb)(context ctx, void * priv, struct X * the_reply);

context lib_connect();
bool lib_send_message(context ctx, message msg, got_message_reply_cb callback, void * priv);

I believe this is pretty straight-forward to understand.

So, I'm trying to wrap that black-box native library into something like:

class TheLibrary : public Nan::ObjectWrap {
    Initialize(v8::Handle<v8::Object> target);
    SendMessage(...)
}

And then to javascript object like:

class TheLibrary {
    SendMessage(message: whatever, callback: (reply) => void); // or return promise, doesn't matter
}

How to do the actual handling of the callback in the NAN C++ module? I need to somehow pass the callback (represented probably by Local<Function> - which have, if I understand it correctly, limited scope) as a pointer to the function and then retrieve it back. How to do that? Thanks for your replies.

like image 650
Mike S. Avatar asked Nov 09 '18 19:11

Mike S.


1 Answers

The high level answer is that you don't pass the JS callback function directly, but pass in a pointer to a function that somehow has your JS callback as a context value (in your example the priv parameter).

So for your case you write something like this:

void TheLibraryCallback(context ctx, void *instance, struct X *the_reply) {
    ((TheLibrary*)instance)->callback(ctx, the_reply);
}

In your TheLibrary you add a method void callback(context ctx, struct X * the_reply) that handles the callback. You call your library like this: lib_send_message(ctx, msg, TheLibraryCallback, this); with this being a TheLibrary instance.

So how do you call back the JS callback in your callback method? With nan you will have to make sure you are back in the main thread. There are examples out there, but I would suggest that you use the new N-API instead. The AsyncWorker helps with the boilerplate that you need to do to call the callback in the main thread.

like image 179
Fozi Avatar answered Nov 11 '22 10:11

Fozi