了解节点插件 API (N-API) HandleScope [英] Understanding Node Addon API (N-API) HandleScope

查看:168
本文介绍了了解节点插件 API (N-API) HandleScope的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解如何正确使用 HandleScopeEscapableHandleScope.例如,来自 这个节点示例:

I have difficulties to understand how to correctly use HandleScope and EscapableHandleScope. For example, from this Node example:

MyObject::MyObject(const Napi::CallbackInfo& info) : Napi::ObjectWrap<MyObject>(info) {
  Napi::Env env = info.Env();
  Napi::HandleScope scope(env);

  this->val_ = info[0].As<Napi::Number>().DoubleValue();
};

为什么在这种情况下我们需要创建一个新的 HandleScope?来自 另一个例子:

Why do we need to create a new HandleScope in this case? And from this other example:

Napi::Object CreateObject(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  Napi::Object obj = Napi::Object::New(env);
  obj.Set(Napi::String::New(env, "msg"), info[0].ToString());

  return obj;
}

为什么这里不需要它?

另外,我没有找到任何使用 EscapableHandleScope 的例子,什么时候需要这个?

Also, I didn't find any example using EscapableHandleScope, when is this needed?

推荐答案

有关 HandleScopes 是什么及其用途的说明,请参阅 V8 的文档,例如对于 Local 类:

For an explanation of what HandleScopes are and what to use them for, see V8's documentation, e.g. for the class Local:

有两种类型的句柄:本地句柄和持久句柄.

There are two types of handles: local and persistent handles.

局部句柄是轻量级和瞬态的,通常用于本地操作.它们由 HandleScopes 管理.这意味着一个HandleScope 在创建时必须存在于堆栈中,并且它们仅在 HandleScope 活动期间有效创建.为了将本地句柄传递给外部 HandleScope,一个必须使用 EscapableHandleScope 及其 Escape() 方法.

Local handles are light-weight and transient and typically used in local operations. They are managed by HandleScopes. That means that a HandleScope must exist on the stack when they are created and that they are only valid inside of the HandleScope active during their creation. For passing a local handle to an outer HandleScope, an EscapableHandleScope and its Escape() method must be used.

对于 HandleScope 类:

一个堆栈分配的类,用于管理多个本地句柄.后已创建句柄范围,将分配所有本地句柄在该句柄范围内,直到删除句柄范围或创建另一个句柄范围.如果已经有一个句柄范围并且创建了一个新的,所有的分配都将在新的处理范围直到它被删除.之后,新的手柄将再次在原始句柄范围内分配.

A stack-allocated class that governs a number of local handles. After a handle scope has been created, all local handles will be allocated within that handle scope until either the handle scope is deleted or another handle scope is created. If there is already a handle scope and a new one is created, all allocations will take place in the new handle scope until it is deleted. After that, new handles will again be allocated in the original handle scope.

本地句柄的句柄作用域被删除后的垃圾收集器将不再跟踪存储在句柄中的对象,并且可能解除分配它.访问句柄的行为句柄范围已删除未定义.

After the handle scope of a local handle has been deleted the garbage collector will no longer track the object stored in the handle and may deallocate it. The behavior of accessing a handle for which the handle scope has been deleted is undefined.

务实:

  • 当从 JavaScript 调用到 C++ 时,如果 C++ 代码创建了任何 Local<>,您将需要至少一个 HandleScope.通常只有一个 HandleScope 是正确的数字.
  • 创建和销毁 HandleScope 是有成本的,所以如果你有很多细粒度的 HandleScope,你就是在浪费时间.另一方面, HandleScope (按照设计,这就是它的目的!)保持其中包含的句柄所指的所有对象都处于活动状态(在 GC 意义上),因此对于非常长时间运行的代码或具有多次迭代的循环,您可能希望引入短期的 HandleScopes,以便可以释放已完成的临时对象.
  • 如文档所述,如果您想在作用域生命周期结束后返回对象,则需要一个 EscapableHandleScope.
  • When calling from JavaScript into C++, you'll need at least one HandleScope if the C++ code creates any Local<>s. Usually exactly one HandleScope is the right number.
  • There's a cost to creating and destroying HandleScopes, so if you have many fine-grained HandleScopes, you're wasting time. On the other hand, a HandleScope (by design, that's its purpose!) keeps all objects alive (in the GC sense) that the handles contained in it are referring to, so for very long-running code, or loops with many iterations, you may want to introduce short-lived HandleScopes so that temporary objects you're done with can be freed.
  • As the documentation says, you need an EscapableHandleScope if you want to return an object beyond the end of the lifetime of the scope.

这篇关于了解节点插件 API (N-API) HandleScope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆