V8:将对象从 JavaScript 传递到 uv_work 函数

标签 v8

好的,我有一个 C++ 函数,需要从 JavaScript 调用,其中一个参数是 JavaScript 对象。 JavaScript 看起来像这样:

var message = {
    fieldA: 42,
    fieldB: "moo"
};

myObj.send(message, function (err) { console.log("Result: " + err); });

在 send() 例程中,我需要调用另一个可能会阻塞的 C 库中的 native 函数。该库中的所有函数都可能会阻塞,因此我一直在广泛使用 uv_queue_work 。

这个例程是我第一次遇到问题,这是因为 JavaScript 对象。 C++ 代码如下所示:

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());
}

这一切都很好,当我尝试访问 SendMessageWorker 函数中的 request->message 时,问题就出现了。

void SendMessageWorker(uv_work_t* req)
{
    SendMessageRequest* request = (SendMessageRequest*)req->data;
    Local<Array> names = request->message->GetPropertyNames();
    // CRASH

似乎从 request->message 调用方法会导致在一个非常小的地址上发生访问冲突(可能是 V8/节点中某处的 NULL 指针引用)。所以直接使用request->message肯定是错误的。我知道要访问回调函数我需要这样做:

request->callback->Call(Context::GetCurrent()->Global(), 1, argv);

我是否需要使用 Context::GetCurrent()->Global() 才能访问由持久模板包装的 Object 类的方法?如果是这样我该怎么做?

最佳答案

SendMessageWorker 中的代码不在 JavaScript 上执行 - uv_queue_work 所做的是在单独的线程中执行 SendMessageWorker,因此它可以让 Node.js 代码也运行,当它准备好时,SendMessageWorkerComplete 将在 JavaScript 线程上执行。

所以你不能在 SendMessageWorker 中使用 JavaScript 变量 - 如果你确实需要,你必须将它们转换为例如调用 uv_queue_work 之前的 C++ 字符串。

关于V8:将对象从 JavaScript 传递到 uv_work 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11110369/

相关文章:

V8引擎的javascript语言规范

Javascript Engine V8 快速属性访问

python - 嵌入在 C++ 中的 Lua 是否能够拥有持久的局部变量?如果没有,是否有脚本语言可以做到?

c++ - 字符串::新:它是什么?

V8 中 Javascript 的奇怪性能

node.js - 是否可以让 Node.js 使用 Rhino 作为 Javascript 引擎?

javascript V8优化和 "leaking arguments"

google-chrome - 将 Chrome/V8 --trace-gc 输出写入文件 - stdout 重定向不起作用

c++ - 如果整数初始化为空,则给整数一个默认值

node.js - Utf8Value 错误 C2661 : No overloaded function takes 2 arguments