c++创建的(napi_create_object),或者作为参数传下来的js value,如果想持久持有,需要怎么做?以及怎么主动销毁或减少引用计数 ?

c++创建的(napi_create_object),或者作为参数传下来的js value,如果想持久持有,需要怎么做?以及怎么主动销毁或减少引用计数

阅读 4.3k
avatarAI BotBETA

在 Node.js 的 N-API 中,当 C++ 创建了一个 JavaScript 对象(使用 napi_create_object)或者接收了一个 JavaScript 值作为参数时,这个值在 C++ 代码中默认是临时持有的。如果你希望 C++ 持久持有这个值,你需要增加它的引用计数。同样地,如果你想释放这个值,你需要减少它的引用计数。

持久持有 JavaScript 值

要持久持有 JavaScript 值,你需要调用 napi_ref 函数。这个函数会增加 JavaScript 值的引用计数。当调用 napi_ref 后,即使没有其他引用指向这个值,Node.js 也不会自动回收它,直到你显式地释放它。

napi_value jsValue; // 假设这是通过 napi_create_object 或其他方式获得的 JavaScript 值
napi_ref ref;

// 持久持有这个值
napi_status status = napi_ref(env, jsValue, &ref);
if (status != napi_ok) {
  // 处理错误
}

主动销毁或减少引用计数

要释放一个持久持有的 JavaScript 值,你需要调用 napi_unrefnapi_delete_referencenapi_unref 会减少值的引用计数,而 napi_delete_reference 会释放对值的引用并可能触发其回收。

// 减少引用计数
napi_status status = napi_unref(env, ref);
if (status != napi_ok) {
  // 处理错误
}

// 释放引用
status = napi_delete_reference(env, ref);
if (status != napi_ok) {
  // 处理错误
}

注意,你不能在减少引用计数之后立即释放引用,因为这可能导致引用计数变成负数。通常,你应当在知道不会再需要该值时减少引用计数,并在适当的时候(例如在回调函数的执行结束后)释放引用。

注意事项

  • 确保在合适的时机减少和释放引用,以避免内存泄漏。
  • 在释放引用之前,不要假设 Node.js 会自动回收值。只有当引用计数减少到 0 时,Node.js 才会回收值。
  • 如果你的 C++ 代码在多个线程中使用 N-API,你需要确保对同一个值的引用计数操作是线程安全的。

最后,请确保你遵循 Node.js 和 N-API 的最佳实践,包括错误处理、资源管理以及线程安全。

1 个回答

持久持有一个对象,可以通过napi_create_reference创建一个强引用,然后将这个ref保存下来使用;主动销毁可以使用napi_delete_reference,减少或者增加引用计数可以通过napi_reference_unref或者napi_reference_ref

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进