【问题标题】:Prevent v8::Local value from being garbage collected防止 v8::Local 值被垃圾收集
【发布时间】:2016-02-07 02:07:41
【问题描述】:

我有一个函数,它将参数的值存储到 C++ 类的 std::vector<v8::Local<v8::Value>> 属性中,像这样公开为 ObjectWrap:

NAN_METHOD(MyObject::Write) {
  MyObject* obj = Nan::ObjectWrap::Unwrap<MyObject>(info.This());
  obj->data.push_back(info[0]);
}

但是,当我尝试从另一个 C++ 函数读回值时,该值丢失,变为undefined

我将一个数字传递给MyObject::Write,我可以确认info[0]-&gt;IsNumber() 在将其推送到向量之前返回true,但是在读回它时,值它不是编号,实际上对于我使用来自 v8::ValueIs&lt;Type&gt; 方法测试的所有类型返回 false,但对于 BooleanValue() 仍然返回 true

我的猜测是该变量在MyObject::Write 返回后被垃圾回收,但我不知道如何防止这种情况发生。


我目前正在尝试将该值初始化为Persistent 值。我尝试了以下尝试但没有成功:

Nan::CopyablePersistentTraits<v8::Value>::CopyablePersistent p;
Nan::Persistent<v8::Value> persistent(info[0]);
Nan::CopyablePersistentTraits::Copy(persistent, p);

还有:

v8::Isolate *isolate = info.GetIsolate();
v8::Persistent<v8::Value, v8::CopyablePersistentTraits<v8::Value>> persistent(isolate, info[0]);

但是遇到大量 C++ 错误。

【问题讨论】:

    标签: c++ garbage-collection v8


    【解决方案1】:

    我自己解决这个烂摊子时遇到了问题。这里有很多我们都错过的模板内容。这是我发现最具可读性的解决方案:

    // Define the copyable persistent
    v8::CopyablePersistentTraits<v8::Value>::CopyablePersistent p;
    
    // Create the local value
    auto val = v8::Local<v8::Value>::New(
        v8::Isolate::GetCurrent(), //< Isolate required
        v8::Integer::New(v8::Isolate::GetCurrent(), v) //< Isolate required
    );
    
    // Reset() is a TEMPLATE FUNCTION, you have to template it with the same
    // template type parameter as the v8::Local you are passing
    p.Reset<v8::Value>(v8::Isolate::GetCurrent(), val); //< Isolate required
    

    “信息”我假设您指的是 v8::FunctionCallbackInfo 参考。如果是这样,上面的代码将折叠成以下内容:

    void SomeFunc(v8::FunctionCallbackInfo<v8::Value>& info) {
        v8::CopyablePersistentTraits<v8::Value>::CopyablePersistent p;
        p.Reset<v8::Value>(info[0]);
    }
    

    因为持久化现在是可复制的,所以您可以将其存储在标准库容器中。这是我的用例。这是将值存储在向量中的示例:

    std::vector<v8::CopyablePersistentTraits<v8::Value>::CopyablePersistent> vect;
    
    void AccumulateData(v8::FunctionCallbackInfo<v8::Value>& info) {
        v8::CopyablePersistentTraits<v8::Value>::CopyablePersistent p;
        p.Reset<v8::Value>(info[0]);
        vect.push_back(p);
    }
    

    我希望这对那里的人有所帮助。

    【讨论】:

      【解决方案2】:

      如果您计划在 C++ 中存储 v8 值,则需要使它们持久化而不是本地化,以便它们独立于句柄范围,并且在释放句柄范围时不会被垃圾收集。

      Nan has version-independant wrappers for v8::Persistent and Co. 由于在 std::vector&lt;&gt; 内部使用,您还需要使用 Nan::CopyablePersistentTraits 初始化 Nan::Persistent 以便它变得可复制(或为它)。

      【讨论】:

      • 感谢您提供信息,但我似乎无法正确初始化Persistent。我正在尝试: v8::Isolate *isolate = info.GetIsolate(); v8::Persistent<:value v8::copyablepersistenttraits>> 持久(隔离,信息 [0]);还有这个: Nan::CopyablePersistentTraits<:value>::CopyablePersistent p; Nan::Persistent<:value> 持久的(info[0]); Nan::CopyablePersistentTraits::Copy(persistent, p);但是得到了大量的错误。你有我可以看到的代码示例吗?
      • 嗯,所以 cmets 似乎没有正确处理代码块。为了便于阅读,我将使用上述信息编辑我的主要问题。
      • 试试Nan::CopyablePersistentTraits&lt;v8::Value&gt;::CopyablePersistent p; p.Reset(isolate, info[0]);
      • 我收到error: assigning to 'v8::Object *volatile' from incompatible type 'v8::Primitive *' (pastebin.com/Wdbeir34)
      猜你喜欢
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      相关资源
      最近更新 更多