OK, I have a function in C++ that I need to call from JavaScript, and one of the parameters is a JavaScript object. The JavaScript looks like this:
var message = {
fieldA: 42,
fieldB: "moo"
};
myObj.send(message, function (err) { console.log("Result: " + err); });
In the send() routine I need to call a native function in another C library that may block. All functions in this library may block so I’ve been using uv_queue_work extensively.
This routine is the first time I’ve hit an issue and it is because of the JavaScript object. The C++ code looks like this:
struct SendMessageRequest
{
Persistent<Object> message;
Persistent<Function> callback;
int result;
};
Handle<Value> MyObj::Send(const Arguments& args)
{
HandleScope scope;
// Parameter checking done but not included here
Local<Object> message = Local<Object>::Cast(args[0]);
Local<Function> callback = Local<Function>::Cast(args[1]);
// Send data to worker thread
SendMessageRequest* request = new SendMessageRequest;
request->message = Persistent<Object>::New(message);
request->callback = Persistent<Function>::New(callback);
uv_work_t* req = new uv_work_t();
req->data = request;
uv_queue_work(uv_default_loop(), req, SendMessageWorker, SendMessageWorkerComplete);
return scope.Close(Undefined());
}
This is all fine, the problem comes when I try to access request->message in the SendMessageWorker function.
void SendMessageWorker(uv_work_t* req)
{
SendMessageRequest* request = (SendMessageRequest*)req->data;
Local<Array> names = request->message->GetPropertyNames();
// CRASH
It seems that calling methods off of request->message causes an Access Violation on a really small address (probably a NULL pointer reference somewhere in V8/node). So using request->message directly must be wrong. I know to access the callback function I need to do this:
request->callback->Call(Context::GetCurrent()->Global(), 1, argv);
Do I need to use Context::GetCurrent()->Global() in order to access methods off of the Object class that is wrapped by the Persistent template? If so how do I do that?
The code in
SendMessageWorkeris not executed on the JavaScript – whatuv_queue_workdoes is execute yourSendMessageWorkerin a separate thread, so it can let the node.js code run as well, and when it’s ready,SendMessageWorkerCompleteis executed back on the JavaScript thread.So you can’t use JavaScript variables in SendMessageWorker – if you really need to, you’d have to convert them to e.g. C++ string before calling
uv_queue_work.